使用外键保存Django ModelForm
使用外键保存Django ModelForm
这可能是一个相当简单的问题,但我在Django文档中找不到答案。我想一次保存两个ModelForms,其中一个是另一个的外键。我不确定如何在视图中编写逻辑以确保它们正确关联。\nmodels.py\n
class Address(models.Model): address = models.CharField(max_length=100) city = models.CharField(max_length=50) zipcode = models.PositiveIntegerField() class Store(models.Model): name = models.CharField(max_length=100) description = models.CharField(max_length=140, blank=True) address = models.ForeignKey(Address, null=True)
\nforms.py\n
class CreateStore1Form(forms.ModelForm): class Meta: model = Store exclude = ('address',) class CreateStore2Form(forms.ModelForm): class Meta: model = Address
\nviews.py\n
@login_required def create(request): if request.method == "POST": form1 = CreateStore1Form(request.POST) form2 = CreateStore2Form(request.POST) if form1.is_valid() and form2.is_valid(): store = form1.save(address) new_address = form2.save(commit=False) new_address.store = store mew_address.save() else: form1 = CreateStore1Form() form2 = CreateStore2Form() return render(request, 'create.html', locals())
\n非常感谢您的帮助!
问题的出现原因:在Django中,当使用ModelForm保存带有外键的模型时,需要使用inline formsets来处理相关对象。
解决方法:
1. 在forms.py文件中定义AddressForm和StoreForm两个ModelForm类,分别对应Address和Store模型。在StoreForm中通过exclude属性排除address字段。
2. 在views.py文件中导入inlineformset_factory函数,并在create函数中调用该函数创建一个AddressInlineFormSet对象,该对象用于处理Address和Store之间的关联。
3. 在create函数中判断请求的方法是否为POST,如果是POST请求,则实例化StoreForm并验证表单数据的有效性。
4. 如果StoreForm的数据有效,则通过save方法保存表单数据,并创建一个新的Store对象new_store。
5. 接着,实例化AddressInlineFormSet对象,并传入request.POST、request.FILES和new_store作为参数。
6. 判断AddressInlineFormSet的数据是否有效,如果有效,则通过save方法保存地址数据,并重定向到某个URL。
7. 如果AddressInlineFormSet的数据无效,则将错误信息传递给模板,并显示在页面上。
在Django中,当我们需要保存带有外键的模型时,需要使用inline formsets来处理相关对象。Django为此提供了inline formsets的机制,它是在模型表单集之上的一个小抽象层。它简化了通过外键关联的相关对象的处理。
在这个问题中,我们有两个模型:Address和Store。我们需要保存一个商店的信息,其中商店与地址之间存在外键关联。为了实现这个目标,我们需要使用inline formsets来处理这种情况。
首先,在forms.py文件中定义了AddressForm和StoreForm两个ModelForm类。AddressForm对应Address模型,而StoreForm对应Store模型。在StoreForm中,我们通过exclude属性排除了address字段,因为我们将在inline formset中处理它。
接下来,在views.py文件中,我们导入了inlineformset_factory函数。然后,在create函数中调用该函数,创建了一个AddressInlineFormSet对象。这个对象用于处理Address和Store之间的关联。我们传入Address和Store模型以及AddressForm作为参数。
在create函数中,我们首先判断请求的方法是否为POST。如果是POST请求,我们实例化了StoreForm并验证了表单数据的有效性。如果StoreForm的数据有效,我们通过save方法保存了表单数据,并创建了一个新的Store对象new_store。
接下来,我们实例化了AddressInlineFormSet对象,并传入request.POST、request.FILES和new_store作为参数。然后,我们判断AddressInlineFormSet的数据是否有效。如果有效,我们通过save方法保存了地址数据,并重定向到某个URL。
如果AddressInlineFormSet的数据无效,我们将错误信息传递给模板,并显示在页面上。
通过以上步骤,我们成功解决了使用ModelForm保存带有外键的模型的问题。使用inline formsets可以更方便地处理相关对象之间的关联,并有效地保存数据。