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フィールドです。m[2]のsave()
値をオーバーライドすると、保存されませんが、form_valid
をオーバーライドすると、節約。
Manytomanyの問題について私が推測するのは、それらが実行する順序です...フォーム>管理>モデル、form_validを使用すると、チェーン内の他のことを確認する前に最初に実行しますが、保存を使用すると、最後になります。または他のもの...
最良の方法は、常にraw saveではなくform_validを使用することです
form_valid最初に、ネイティブ検証エラーまたはカスタム検証があるかどうかClean関数を確認し、次にモデルのみを保存します
save検証なしで保存し、検証付きのフォームで保存します
例
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/
_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/')
_