帮助django中涉及模型表单的编程模式

时间:2010-11-19 10:35:42

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

我的问题有点长,因为我缺乏良好的编程习惯,尤其是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)
    #...

问题

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

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

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

表单

对于客户,我创建了三个ModelForms:

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:对于已登录和未登录的用户,添加新订阅。

我怎样才能以最简单的方式处理这两种情况?新订阅formset必须不了解现有订阅。

问题是

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

  1. 获取表单视图:表单将呈现给用户。
  2. POST表单:表单已经过验证。如果错误:转到第1点。如果成功:在会话中保存POST数据。
  3. 获取确认视图:要购买的产品摘要。
  4. GET确认付款:根据所选的付款方式,此处的流程可能会有所不同。
  5. GET thankyou page
  6. 对于已登录和未登录的用户,我可以做一个单一的订阅过程吗?

    我曾想过某种类型的对象,比如黑盒子,它接收输入并返回一个客户(现有或不存在,具体取决于用户是否已注册)以及所有订阅和用户,都准备好存储在数据库中。

    但我不知道该怎么做。

    (如果你到目前为止读到的话,你必须非常好。谢谢!)

1 个答案:

答案 0 :(得分:1)

我无法看到是什么阻碍了您将“黑盒”建模适合现有数据模型。

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

是否有任何特定的地方让你被击中?