15

関連モデルを保存するときに、多対多のモデルを更新しようとしています。これは、 m2m_changed シグナルを使用して可能にする必要があります(そして、機能します!しかし、管理者ではできませんか?)。

# i want the references field to update when related model is saved.
# so just call count_references

class Tag(models.Model):
    """Group everything into categories"""
    # stuff stuff stuff
    references = models.IntegerField(default=0, editable=False)

    def count_references(self):
        # just add up references each time to save headaches
        self.references = 0
        # search for reverse managers
        sets = re.compile('^\w+_set$')
        for rel_set in [method for method in dir(self) if sets.match(method)]:
            self.references += getattr(self, rel_set).count()
        self.save()

class Entry(models.Model):
    """Blog entry"""
    # stuff stuff stuff
    tags = models.ManyToManyField('Tag', blank=True)

# this will call count_references when entry adds or removes tags

@receiver(m2m_changed, sender=Entry.tags.through)
def update_tag_ref_count(sender, instance, action, reverse, model, pk_set, **kwargs):
    print action
    if not reverse and action == 'post_add' or action == 'post_remove':
        for tag_pk in pk_set:
            print tag_pk
            Tag.objects.get(pk=tag_pk).count_references()
            print Tag.objects.get(pk=tag_pk).references

シェルで実行すると、すべてが完全に機能します。たとえば、次のように tests.py を使用します。

t = Tag.objects.all()[0]
s = Snippet.objects.all()[0]

s.tags.remove(t)
s.save()

s.tags.add(t)
s.save()

次の結果が得られます (「test」は出力されるタグ名です):

pre_remove
post_remove
test
0
pre_add
post_add
test
1

完全!そして、管理者のエントリにタグを追加すると、次のようになります (HTTP の間):

pre_clear
post_clear
pre_add
post_add
test
1

まだいい!pre/post_clear が何のために呼び出されたのかわかりません...そして削除すると:

pre_clear
post_clear

ああ!pre/post_remove は呼び出されません! pre/post_clear は役に立たないだけでなく、主キーも提供しません。これは管理者実装のバグのように感じます。助言がありますか?

更新:バグ #16073が提出され、承認されました。

4

1 に答える 1

2

(これをコミュニティ wiki として作成し、これを「未回答」の質問として締めくくります。)

これは Django のバグです。OP はhttps://code.djangoproject.com/ticket/16073でチケットを提出しました。

于 2012-02-27T22:43:26.553 に答える