我有一种情况,我需要做一些类似于在formset中呈现formset的事情。但在转向解决方案之前,我更关注问题。
首先是英语:
现在的模型(为简洁起见而简化):
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)
我目前在CheckOut:ShipmentLine的1:M关系约束下运行良好。然而,当将其改为M:M时,事情会变得非常明显。 在1:M版本中,Shipment表单(加上ShipmentLines的formset)如下所示:
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来过滤这些)
在我的脑海中,我有几种可能性:
我希望我已经正确而清楚地解释了它。它是我遇到的Django表单中最复杂的应用程序,我不确定每个选项的限制/优缺点是什么。
有没有人遇到过这种情况并有解决方案?或者对明智的任何话语?
我提前感谢,
森
答案 0 :(得分:0)
我有类似的情况,我正在做类似你的第二和第三选择:
我已经覆盖了__init__()
,并且在调用super
之后,我有一个循环为每个字段添加一个值选择器(当然你可以在这里使用一个自定义元素)
然后覆盖save()
并在调用super
后,我处理添加所有值的额外字段。