1

異なるモデルに同じ views.py を使用しているため、views.py にフォームを保存する前に、フォームに m2m リレーションがあるかどうかを確認する必要がある状況があります。

例:

#models.py
class BaseClass(models.Model):
   # Some generic stuff.

class SomeClass(BaseClass):
   # This class doesnt have any many2many relations

class SomeOtherClass(BaseClass):
   # This class has many2many relations

#views.py
def do_some_stuff(request):
   # Instantiate a form
   # Save it in a normal way
   form.save()
   # Now, in here while saving I need to check if the form has any 
   # m2m relations so I can use the save_m2m() function after form.save()

より安全な側にいるために、そこに追加のチェックが必要です。これを回避する方法はありますか?前もって感謝します

4

4 に答える 4

0

実際、は常に。の後にインスタンスにsave_m2m()注入されます。モデルにフィールドがない場合でも。ModelFormsave(commit=False)ManyToMany

save_m2m関数のソースは次のとおりです。

def save_m2m():
    opts = instance._meta
    cleaned_data = form.cleaned_data
    for f in opts.many_to_many:
        if fields and f.name not in fields:
            continue
        if f.name in cleaned_data:
            f.save_form_data(instance, cleaned_data[f.name])

ManyToManyフィールドがない場合( instance._meta.many_to_many= [])、何も行われません。

save_m2mしたがって、すべての場合に安全に電話をかけることができます。

于 2010-01-20T18:29:03.730 に答える
0

アントニーは正しく、さらに簡単です。ドキュメントから引用します:

commit=Falseモデルが別のモデルと多対多の関係にある場合、使用の別の副作用が見られます。モデルに多対多の関係がありcommit=False、フォームを保存するときに指定した場合、Django は多対多の関係のフォーム データをすぐに保存できません。これは、インスタンスがデータベースに存在するまで、インスタンスの多対多データを保存できないためです。

この問題を回避するために、 を使用してフォームを保存するたびにcommit=False、Django はsave_m2m()ModelForm サブクラスにメソッドを追加します。

それによると、メソッドでフォームを保存しないと、多対多の関係が存在しても存在しません。commit=Falsesave_m2m()

Pythonのモットー「許可よりも許しを求める方が簡単」に忠実に、次のこともできます。

try:
    form.save_m2m()
except:
    pass

あなたが本当にしたい場合。

于 2010-01-20T17:37:40.463 に答える
0

これに対する考えられる解決策を見つけました。

次のようなものを使用できます。

if len(form_instance._meta.many_to_many) > 0:
   for i in form_instance._meta.many_to_many:
      if type(i) = ManyToManyField:
         form_instance.save_m2m()
         break
于 2010-01-20T14:58:20.907 に答える
0
if hasattr(form, 'save_m2m'):
    form.save_m2m()

引数を指定しsave_m2mて呼び出す場合にのみ必要な (そして存在する) だけであることに注意してください。デフォルトのままで保存すれば不要です。form.savecommit=Falsecommit=Truesave_m2m

于 2010-01-20T10:24:26.917 に答える