Code

Opened 4 years ago

Closed 4 years ago

#13713 closed (invalid)

Changing ModelMultipleChoiceField in admin is not reflected in override save() of the same model

Reported by: jonathan_livni Owned by: nobody
Component: Uncategorized Version: 1.2
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Consider the following:

class MyModel1 (models.Model):
    name                = models.CharField(max_length=200)

class MyModel2 (models.Model):
    my_model_1          = models.ManyToManyField(MyModel1, blank=True,null=True)
    city                = models.CharField(max_length=200)

    def save(self, *args, **kwargs):
        print (",".join([mm1.name for mm1 in self.my_model_1.all()]))
        print (self.city)
        super(Filter, self).save(*args, **kwargs)
        print (",".join([mm1.name for mm1 in self.my_model_1.all()]))
        print (self.city)

Admin presents my_model_1 field as ModelMultipleChoiceField widget.
Try changing this multi-choice field in admin a few times and you'll discover the bug...
self.city prints out with the updated value, the one you entered in the admin form, both before and after the super()
but... self.my_model1 retains the previous values in the printout, both before and after the super(), although in the db it is updated after the save() completes.

btw, this is the real but and not this - my bad

Attachments (0)

Change History (7)

comment:1 Changed 4 years ago by jonathan_livni

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

typo when I copied here on the super() row. Should be:

super(MyModel2, self).save(*args, **kwargs)

doesn't change the bug - it's still there
How come I can't edit my bug submission?

comment:2 Changed 4 years ago by jonathan_livni

Further discoveries - if I insert anywhere inside the override save() the following:

my_model_1 = MyModel1.objects.all()

then it doesn't work! after the save() completes, my_model_1 does not retain the value given inside the save()

comment:3 follow-up: Changed 4 years ago by suzaku

Is it possible that this is caused by cached query result?

comment:4 in reply to: ↑ 3 Changed 4 years ago by jonathan_livni

Replying to suzaku:

Is it possible that this is caused by cached query result?

If so, why is it true for M2M relations and not for all other relations?
Also - how can I check this?

comment:5 follow-up: Changed 4 years ago by russellm

  • Resolution set to invalid
  • Status changed from new to closed

It's not a queried cache result - it's correctly returning the values from the database at the point at which you are querying.

M2M relations aren't saved as part of the save() call - they're a separate table, and they're saved separately, after the base model has been saved.

I don't know what has given you the impression that the m2m is updated as part of the model save. It is modified as part of the *form* save, but that's a larger process than saving an individual model instance.

comment:6 in reply to: ↑ 5 Changed 4 years ago by jonathan_livni

  • Resolution invalid deleted
  • Status changed from closed to reopened

Replying to russellm:

Thank you for clarifying that. But what happens if I need to use the M2M data as part of the save()? How can I access it?
If there is no way to access it then it may not be an implementation bug, but it is a design bug. Therefor I'm reopening the ticket.

comment:7 Changed 4 years ago by russellm

  • Resolution set to invalid
  • Status changed from reopened to closed

If you want to ask how to do something, the right place isn't on a ticket -- it's on django-users.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.