【问题标题】:Help with a programming pattern in django that involves model forms帮助 django 中涉及模型表单的编程模式
【发布时间】:2010-11-19 10:35:42
【问题描述】:

由于我缺乏良好的编程实践知识,尤其是 Django,我的问题有点长。我很感激任何建议。

模型(简化)

class Customer(models.Model):
    # Customer info
    first_name = models.CharField(max_length=75)
    last_name  = models.CharField(max_length=179, null=True, blank=True)
    # ... and more fields that need validation but not needed for the question
    pay_method          = models.CharField(max_length=1, choices=PAY_METHODS)
    bank_code           = models.CharField(max_length=4, blank=True, null=True)
    bank_office_code    = models.CharField(max_length=4, blank=True, null=True)
    bank_control_digit  = models.CharField(max_length=2, blank=True, null=True)
    bank_account_number = models.CharField(max_length=10, blank=True, null=True)

class Product(models.Model):
    name = models.CharField(max_length=50)

class Subscription(models.Model):
    customer = models.ForeignKey(Customer)
    product  = models.ForeignKey(Product)
    user     = models.OneToOneField(User)
    # ...
    start_date = models.DateField(null=True)
    end_date   = models.DateField(null=True)
    # ...
    is_main_subscription = models.BooleanField(default=False)

class Invoice(models.Model):
    customer = models.ForeignKey(Customer)
    subscriptions = models.ManyToManyField(Subscription,null=True,blank=True)
    #...

问题

有两个非常相似的订阅过程。一个用于新用户,另一个用于现有用户。

对于新用户,订阅过程包括在客户表中填写客户的个人数据和付款信息,并创建至少一个订阅。每个订阅都指一个产品。在流程结束时,将为所有这些订阅生成一张发票。我认为这里不需要 Invoice 模型,但我把它放在这里以防万一。每个订阅都有一个 django-contrib-auth 用户来登录应用程序。

第一个订阅是主订阅。与该订阅关联的用户可以续订或取消其他订阅并购买新订阅。该新流程涉及在需要时更改付款信息,但不会更改客户的个人数据。而且我们必须区分现有订阅和新订阅。

表格

我为客户创建了三个模型表单:

PaymentForm 单独用于订阅过程中的登录用户

class PaymentForm(forms.ModelForm):
    class Meta:
        model = Customer
        fields = (
            'pay_method',
            'bank_code',
            'bank_office_code',
            'bank_control_digit',
            'bank_account_number'
        )
    # ...

DataForm 单独用于订阅为主订阅的登录用户在订阅过程之外编辑客户个人信息。

class DataForm(forms.ModelForm):
    class Meta:
        model = Customer
        fields = (
            'first_name',
            'last_name',
            # All the other fields
        )
    # ...

NewCustomerForm 为我创建了一个混合 PaymentForm 和 DataForm 的表单

class NewCustomerForm(MyDataForm, PaymentForm):
    class Meta:
        model = Customer
        fields = MyDataForm.Meta.fields + PaymentForm.Meta.fields

对于订阅,我认为应该有两个 FormSet(内联表单集?):

  • RenewalsFormSet:用于登录用户取消或续订现有订阅。用户无法编辑信息,只能取消或续订。
  • SubscriptionsFormSet:用于已登录和未登录的用户添加新订阅。

如何以最简单的方式处理这两种情况?新订阅表单集必须不知道现有订阅。

问题是

从 Django 视图的角度来看,订阅过程是:

  1. GET 表单视图: 将表单呈现给用户。
  2. POST 表单: 表单经过验证。如果错误:转到第 1 点。如果成功:在会话中保存 POST 数据。
  3. GET 确认视图:要购买的产品摘要。
  4. GET 确认付款:根据选择的付款方式,此处的流程可能会有所不同。
  5. 获取感谢页面

如何为已登录和未登录用户提供单一订阅流程?

我曾考虑过某种对象,例如接收输入并返回所有订阅和用户的客户(是否存在,取决于用户是否已注册)的黑匣子,所有订阅和用户都准备好存储在数据库中。

但我不知道该怎么做。

(如果你读到现在,那你一定很nice。谢谢!)

【问题讨论】:

    标签: django design-patterns django-models django-forms


    【解决方案1】:

    我看不出是什么阻止了您将“黑盒”建模与现有数据模型相匹配。

    您需要做的就是根据用户是否已经订阅来改变您的表单集呈现。如果您还在表单上编写了一个保存方法,该方法更新调用外部网关以更新数据库,则视图将保持完全相同。

    你有没有被击中的具体地方?

    【讨论】:

    • 感谢您的回答。主要是我的无知阻止了我做那个“黑匣子”。我不知道是否有更好的模式可以做到这一点,或者我是否需要两个比一个更好的黑盒,每个黑盒都有自己的额外验证。
    • 我终于在不知情的情况下使用了这种模式,但它在简化应用程序中的支付流程工作流方面效果很好。所以答案是可以的。 ¡ 谢谢!
    猜你喜欢
    • 2013-01-03
    • 1970-01-01
    • 2012-01-12
    • 2011-11-22
    • 2013-10-17
    • 1970-01-01
    • 2011-04-30
    • 2019-04-22
    • 2011-04-13
    相关资源
    最近更新 更多