2010-11-19 62 views
0

由于我缺乏良好的编程实践知识,并且最重要的是Django,所以我的问题有点长。我很欣赏任何建议。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用户登录到应用程序。

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

形式

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

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

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

数据形单独用于记录用户的订阅是订阅过程中编辑客户个人信息的主要订阅。

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 

对于订阅我认为应该有两个表单集(在线表单集?):

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

我怎样才能以最简单的方式处理这两种情况?新的订阅表单不能具有现有订阅的知识。

,问题是

从视图中的Django点意见的订阅过程将是:

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

我能做些什么有一个单一的订阅过程都记录下来,在用户没有登录?

我曾经考虑过某种类似黑箱的对象,它接收所有订阅和用户的输入并返回一个客户(已存在与否,取决于用户是否已注册),所有这些都准备好存储在数据库中。

但我不知道该怎么做。

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

回答

1

我看不出有什么阻止你适合你的“黑盒”造型,以现有的数据模型。

您需要做的只是根据用户是否已订阅而改变您的表单集呈现。如果你还在窗体上写了一个保存方法,它更新调用外部网关来更新数据库,那么视图将保持完全相同。

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

+0

谢谢你的回答。我的无知主要是阻止我做那个“黑匣子”。我不知道是否有更好的模式来做到这一点,或者如果我需要两个比一个更好的黑匣子,每个黑匣子都有自己的附加验证。 – carlosescri 2010-11-19 13:10:05

+0

我终于在没有知识的情况下使用了这种模式,但它在工作流程中简化了付款流程。所以答案是好的。谢谢! – carlosescri 2012-05-28 07:43:11