在Django表单中,为了保存其他数据,我通常使用form_valid()
,但是我也可以使用formclass的save()
方法。
今天,我改写了save()
而不是form_valid()
,但我的manytomanyfield遇到了问题。
使用时,不会保存manytomanyfield的值,但是当我使用form_valid()
时,它们将开始保存。谁能告诉我两者的原因和不同之处,哪一种是最方便的方法?在什么情况下?
这是我重写的save()方法:
class ProductCreateForm(forms.ModelForm):
sizes = make_ajax_field(ProductCreateModel,'sizes','sizes')
colours = make_ajax_field(ProductCreateModel,'colours','colours')
class Meta:
model = ProductCreateModel
fields = ('title','category',
'regions',)
def __init__(self,*args,**kwargs):
self.request = kwargs.pop("request")
super(ProductCreateForm, self).__init__(*args, **kwargs)
def save(self):
product = super(ProductCreateForm, self).save(commit=False)
user = self.request.user
product.location = user.user_location
product.save()
return product
当我重写form_valid()方法时:
def get_form_kwargs(self):
kwargs = super(ProductCreateView,self).get_form_kwargs()
kwargs.update({'request':self.request})
return kwargs
def form_valid(self, form):
product = form.save(commit=False)
user = self.request.user
form.instance.user = user
form.instance.location = user.user_location
form.save()
return super(ProductCreateView, self).form_valid(form)
sizes
,colours
和regions
是m2m字段,正如我在覆盖save()
时覆盖的m2m值,但在覆盖form_valid
时未保存他们开始保存。
答案 0 :(得分:2)
关于您遇到的许多问题,我想是它们执行任务的顺序...表单>管理>模型,当您使用form_valid时,他们首先要做的是检查链中的其他事物,而使用保存是最后一次,也许可能是因为或其他原因...
最好的方法是始终使用form_valid而不是原始保存
form_valid 首先检查“清理”功能是否存在任何本机验证错误或自定义验证,然后才保存模型
保存只是保存而不进行验证,然后将其与表单一起进行验证
示例
from django import forms
class ContactForm(forms.Form):
# Everything as before.
...
def clean(self):
cleaned_data = super().clean()
cc_myself = cleaned_data.get("cc_myself")
subject = cleaned_data.get("subject")
if cc_myself and subject:
# Only do something if both fields are valid so far.
if "help" not in subject:
raise forms.ValidationError(
"Did not send for 'help' in the subject despite "
"CC'ing yourself."
)
来源:https://docs.djangoproject.com/en/2.0/ref/forms/validation/
答案 1 :(得分:2)
如果使用commit=False
保存表单,则必须调用表单的save_m2m
方法来保存多对多数据。有关更多信息,请参见the docs。
如果您决定使用form_valid
方法,我将更改以下内容:
form.save()
返回的实例并保存它,而不是再次调用form.save()
。form.save_m2m()
super().form_valid()
(这将再次保存表单)将它们放在一起,您将得到:
def form_valid(self, form):
product = form.save(commit=False)
product.user = self.request.user
product.location.location = user.user_location
product.save()
form.save_m2m()
return redirect('/success-url/')