#16073: Django admin save not sending post remove action with m2m changed signal
-------------------------+-------------------------------
 Reporter:  sam@…        |          Owner:  nobody
     Type:  Bug          |         Status:  new
Milestone:               |      Component:  contrib.admin
  Version:  1.3          |       Severity:  Normal
 Keywords:  m2m_changed  |   Triage Stage:  Unreviewed
Has patch:  0            |  Easy pickings:  0
-------------------------+-------------------------------
 Hi all

 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$')
         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:

 {{{
 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?

-- 
Ticket URL: <https://code.djangoproject.com/ticket/16073>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to