Django ModelForm继承,子类化和传递实例

时间:2017-07-20 11:42:24

标签: django django-forms

我有一个地址模型:

class Address(models.Model):
  line1 = models.CharField(max_length=100)
  ....

和一个AddressForm:

class AddressForm(forms.ModelForm):
  class Meta:
    model = Address

有几个模型会有一个地址字段,所以我不想复制+粘贴AddressForm中的所有字段,而是想扩展AddressForm,以便重用它。具体来说,我想避免将所有表单字段复制+粘贴到其他应用程序的表单中,并且只有一个AddressForm.is_valid()函数。

例如,订单将有一个地址,所以我的计划是做这样的事情:

class Order:
  address = models.ForeignKey(Address, on_delete=models.CASCADE)

class OrderForm(AddressForm):
  class Meta:
    model = Order

但是,当我从order/views.py将一个实例传递给OrderForm时,我传递一个Order的实例,并且所有的AddressForm字段都显示为空白:

form = OrderForm(instance=order)

如何从order.address字段初始化AddressForm字段?

我试过这个:

class OrderForm(AddressForm):
    def __init__(self, *args, **kwargs):
        kwargs['instance'] = kwargs['instance'].address
        super(OrderForm, self).__init__(*args, **kwargs)

但它不起作用。

有办法做到这一点吗?还是重用AddressForm的更好方法?或者,如果Order是Address的子类,这只会起作用吗?

干杯,

1 个答案:

答案 0 :(得分:2)

如果您不想继承地址,那么您应该在视图中使用两个表单,而不是尝试在订单表单中包含地址字段。

if request.method = "POST":
    address_form = AddressForm(request.POST, instance=order.address)
    order_form = OrderForm(request.POST, instance=order)
    if address_form.is_valid() and order_form.is_valid():
        address = address_form.save()
        order = order_form.save()

您的订单表格应排除Address的外键。

class OrderForm(AddressForm):
    class Meta:
    model = Order
    exclude = ['address']

创建新实例时,应使用commit=False保存订单,设置地址,然后保存订单:

if request.method = "POST":
    address_form = AddressForm(request.POST)
    order_form = OrderForm(request.POST)
    if address_form.is_valid() and order_form.is_valid():
        address = address_form.save()
        order = order_form.save(commit=False)
        order.address = address
        order.save()