Django 管理员保存不发送带有 m2m_changed 信号的 post_remove 操作
当我保存相关模型时,我试图获取多对多模型进行更新。使用 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
在 shell 中运行时,一切都运行良好。例如,使用像这样的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 是无用的,并且它不提供任何主键。这感觉像是管理实施中的一个错误。有什么建议吗?
更新:Bug #16073 提交并接受。
I'm trying to get a many to many model to update when I save a related model. This should be possible using the m2m_changed signal (and it works! but not in the admin?) e.g.
# 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
Everything works perfectly when run in the shell. e.g. with a tests.py like so:
t = Tag.objects.all()[0]
s = Snippet.objects.all()[0]
s.tags.remove(t)
s.save()
s.tags.add(t)
s.save()
I get the following (where 'test' is the tag name being printed):
pre_remove
post_remove
test
0
pre_add
post_add
test
1
perfect! And when I add a tag to an entry in the admin I get the following (between HTTP stuff):
pre_clear
post_clear
pre_add
post_add
test
1
still good! not sure what pre/post_clear was called for... and when I remove:
pre_clear
post_clear
argh! pre/post_remove is not called! pre/post_clear is useless as well as it doesn't provide any primary keys. this feels like a bug in the admin implementation. any suggestions?
Update: Bug #16073 filed and accepted.
)
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
Everything works perfectly when run in the shell. e.g. with a tests.py like so:
I get the following (where 'test' is the tag name being printed):
perfect! And when I add a tag to an entry in the admin I get the following (between HTTP stuff):
still good! not sure what pre/post_clear was called for... and when I remove:
argh! pre/post_remove is not called! pre/post_clear is useless as well as it doesn't provide any primary keys. this feels like a bug in the admin implementation. any suggestions?
Update: Bug #16073 filed and accepted.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
(将其创建为社区 wiki,以将其作为“未回答”的问题来结束。)
这是 Django 中的一个错误。 OP 在 https://code.djangoproject.com/ticket/16073 提交了一张票证。
(Creating this as a community wiki to close out this as an "unanswered" question.)
This is a bug in Django. OP filed a ticket at https://code.djangoproject.com/ticket/16073.