2014-07-27 48 views
0

我有一种情况,我需要做一些类似于在formset中渲染formset的东西。但在跳转到解决方案之前,我宁愿将重点放在问题上。Django(模型)表格字段:Manytomany与键值对

的第一部英文:

  • 我创建从仓库装运。
  • 每个货件可以包含多行(product_type和package_type的唯一组合),并带有item_count
  • 但是,对于每一行,可能会有多个“包” - 具有item_count的product_type的package_type。把它看作一个批次。
  • 客户只对每个product_type/package_type看到一行感兴趣
  • 但是我们需要拉出库存并正确地归属每批中的特定单位以允许库存控制,召回控制等功能。因此,派遣人员对确切地发送哪些包感兴趣。
  • 除此之外,销售人员输入仅指定product_type/package_type的SalesOrder。他们对这些软件包也不感兴趣。 (请考虑下个月的预订订单 - 谁知道现货库存呢?)。

现在的模型(简化为清楚起见):

class Package(models.Model): 
    create_date = models.DateField() 
    quantity = models.FloatField() 
    package_type = models.ForeignKey(PackageType, on_delete=models.PROTECT) 
    product_type = models.ForeignKey(ProductType, on_delete=models.PROTECT) 

class CheckOut(models.Model): 
    package = models.ForeignKey(Package, on_delete=models.PROTECT) 
    create_date = models.DateField() 
    quantity = models.FloatField() 

class Shipment(models.Model): 
    sales_order = models.ForeignKey(SalesOrder, null=True, blank=True) 
    ship_date = models.DateField(default=date.today, 
     verbose_name='Ship Date') 

class ShipmentLine(models.Model): 
    shipment = models.ForeignKey(Shipment, null=True, blank=True) 
    sales_order_line = models.ForeignKey(SalesOrderLine, null=True, blank=True) 
    quantity = models.FloatField(verbose_name='Quantity Shipped') 
    checkout = models.ManytoManyField(CheckOut) 

我现在有它的1约束运作良好:购物结帐的M个关系:ShipmentLine。但是,当将其更改为M:M时,事情会变得格外明显。 在1:M版的出货形式(加表单集的ShipmentLines)看起来是这样的:

class CreateShipmentForm(forms.ModelForm): 
    class Meta: 
     model = om.Shipment 

    contact = forms.ModelChoiceField(
     queryset=om.Contact.objects.filter(is_customer=True, active=True), 
     label='Customer') 
    customer_ref = forms.CharField(required=False, label='Customer Reference') 
    sales_order = forms.ModelChoiceField(queryset=om.SalesOrder.objects.all(), 
     required=False, widget=forms.HiddenInput()) 
    number = forms.CharField(label='Shipment Number', required=False, 
     widget=forms.TextInput(attrs={'readonly': 'readonly'})) 

class CreateShipmentLineForm(forms.ModelForm): 
    class Meta: 
     model = om.ShipmentLine 
     widgets = { 
      'checkout': forms.HiddenInput() 
     } 
    fields = ('package', 'quantity', 'id', 
     'sales_order_line', 'checkout') 

    id = forms.IntegerField(widget=forms.HiddenInput()) 
    sales_order_line = forms.ModelChoiceField(
     widget=forms.HiddenInput(), required=False, 
     queryset=om.SalesOrderLine.objects.all()) 
    package = forms.ModelChoiceField(required=True, queryset=None) # queryset populated in __init__, removed for brevity 

所以对于1:M,我可以选择一个包,设置数量和完成。 对于M:M,我需要选择product_type,package_type,然后选择一个或多个包,并为每个包选择一个数量。 (我将在表单中使用JS来过滤这些)

在我的脑海里,我有几个可能性:

  • 创建一个(孩子)表单集的软件包和数量,包括在每行(父)的形式
  • 创建某种形式的多字段,多值矩阵自定义表单字段并使用它构造一个模式对话框,其中M:M的东西发生并以某种方式将结果保存到表单中验证,保存发生。

我希望我已经正确,清楚地解释了它。这是我遇到的Django表单中最复杂的应用程序,我不确定每个选项的限制/优缺点。

有没有人遇到过这种情况并有解决办法?还是对智者说的话?

我在此先感谢,

弥敦道

回答

0

我有类似的情况,我做这样的事情你的第二个和第三个选项: 我已经覆盖__init__(),并调用super后,我有一个循环为每个字段添加一个值选择器(当然,您可以在这里使用一个自定义元素) 然后覆盖save(),并在调用super后,处理添加所有值的额外字段。

+0

我在考虑选择二。使用Select和NumberInput创建自定义MultiWidget。然后根据需要重复(还没有看到这方面的最佳方式)。并在前端使用JS进行添加/删除。 –

相关问题