Администратор Django сохраняет не отправляя действие post_remove с сигналом m2m_changed
Я пытаюсь обновить модель "многие ко многим" при сохранении связанной модели. Это должно быть возможно при использовании сигнала 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
Все отлично работает при запуске в оболочке. например, с помощью test.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
Argh! pre/post_remove не вызывается! pre/post_clear бесполезен, а также не предоставляет никаких первичных ключей. это похоже на ошибку в реализации администратора. какие-либо предложения?
Обновление: ошибка #16073 подана и принята.
1 ответ
(Создание этого вики-сообщества, чтобы закрыть этот вопрос как вопрос без ответа.)
Это ошибка в Django. ОП подала заявку по адресу https://code.djangoproject.com/ticket/16073.