2016-08-22 6 views
2

Myコンテンツモデルは、タグモデルと多対多の関係にあります。 Contentオブジェクトを保存するときに、関係を動的に追加する必要があります。私はこれを次のようにしています。Djangoのsaveメソッドで多対多リレーションシップを動的に追加する

# models.py 

def tag_content(content_id): 
    obj = Content.objects.get(pk=content_id) 
    print obj # Checking 
    obj.tags = [1, 2, 3] # Adding the relationships using the Tag IDs 

class Tag(models.Model): 
    name = models.CharField(max_length=255) 

class Content(models.Model): 
    title = models.CharField(max_length=255) 
    is_tagged = models.BooleanField(default=False) 
    tags = models.ManyToManyField(Tag, blank=True) 

    def save(self, *args, **kwargs): 
     super(Content, self).save(*args, **kwargs) 
     if not self.is_tagged: 
      tag_content(self.pk) # calling the tagging method 

つまり、Contentオブジェクトが保存されると、タグフィールドは3つの異なるTagオブジェクトモデルに関連付けられます。ちょうどあなたに知らせるために、私はpks = 1、2、3のタグをデータベースに持っています。

ただし、これはうまくいきません。 saveメソッドは、print obj文が機能するので、tag_contentメソッドを呼び出します。ただし、多対多フィールドは設定されておらず、空のままです。面白いのは、シェルで次のコマンドを実行すると、タグフィールドが完全に設定されていることです。

# python manage.py shell 
from myapp.models import * 
obj = Content.objects.get(pk=1) 
tag_content(obj.pk) 

どのようにシェルバージョンが動作しますが、他のバージョンは動作しませんか?どんな助けもありがとうございます。

+1

問題の原因ではありませんが、Contentアイテム自体をpkではなくtag_contentに渡すのはなぜですか?その後、データベースから再クエリする必要はありません。 –

+0

良い点。これを行います。しかし、あなたが言ったように、私の問題の解決策ではありません。 –

答えて

3

カスタムsaveメソッドでm2m関係で作業することはできません.Djangoがそれらの関係をデータベースに書き込む方法のためです。モデルインスタンスをm2mの関係で保存すると、Djangoは最初にオブジェクトを書き込み、次に再び入り、適切なm2m関係を書き込みます。 m2mのものは "second"になるので、カスタムセーブで関係を使って作業しようとすると失敗します。

ソリューションはpost-save signal.は、カスタムのものを保存し、receiverpost_saveをインポートすることを確認すること、お使いのモデルの定義の下にこれを追加と削除]を使用することです。そして、あなたのtag_content機能は、おそらくTrueis_taggedを交換する必要があり

@receiver(post_save, sender = Content) 
def update_m2m_relationships_on_save(sender, **kwargs): 
    if not kwargs['instance'].is_tagged: 
     tag_content(kwargs['instance'].pk) 

とインスタンスを保存します。そのブール値が反転されない場合、これは無限ループで実行される可能性があります。また、単に代わりにPKを渡すのオブジェクトに渡すことができます。

def tag_content(thing_to_tag): 
    thing_to_tag.tags.add([1,2,3]) 
    thing_to_tag.is_tagged = True 
    thing_to_tag.save() 
    return thing_to_tag 

注M2M関係に追加する際に重要である.add()の使用。

+0

申し訳ありませんが、私はこれを試しました。しかし、私は別のエラーを取得し続ける:Unhashable型 'リスト'。 add()関数を参照します。なぜこれが起こっているのか? –

+1

数字のリストの代わりにオブジェクトのクエリセットを追加してみてください – souldeux

関連する問題