Sunday, December 20, 2015

Re: Question re django.forms.models.BaseModelFormSet.save_existing_objects()

On 21/12/2015 6:10 PM, James Schneider wrote:
> I have just been digging into django.forms.models.py
> <http://django.forms.models.py> to debug my own code and found
> something which confuses me in both 1.8 and 1.9
>
> django.forms.models.BaseModelFormSet.save_existing_objects() puts
> objects (child model instances) into the
> BaseModelFormSet.deleted_objects list whether they are deleted or not.
>
> Here is the 1.9 code (no need to show 1.8 because they are both more
> or less the same)
>
> 741 def save_existing_objects(self, commit=True):
> 742 self.changed_objects = []
> 743 self.deleted_objects = []
> 744 if not self.initial_forms:
> 745 return []
> 746
> 747 saved_instances = []
> 748 forms_to_delete = self.deleted_forms
> 749 for form in self.initial_forms:
> 750 obj = form.instance
> 751 if form in forms_to_delete:
> 752 # If the pk is None, it means that the
> object can't be
> 753 # deleted again. Possible reason for this
> is that the
> 754 # object was already deleted from the DB.
> Refs #14877.
> 755 if obj.pk <http://obj.pk> is None:
> 756 continue
> 757 self.deleted_objects.append(obj)
> 758 self.delete_existing(obj, commit=commit)
> 759 elif form.has_changed():
> 760 self.changed_objects.append((obj,
> form.changed_data))
> 761
> saved_instances.append(self.save_existing(form, obj, commit=commit))
> 762 if not commit:
> 763 self.saved_forms.append(form)
> 764 return saved_instances
>
> Line 758 will fail and the object will not be deleted if commit ==
> False but line 757 has already added the object to a list.
>
> Is this intended?
>
>
> Wouldn't L757 only get executed if L751 has already determined that the
> particular object/form is supposed to be deleted, meaning that
> self.deleted_objects would only contain objects/forms that were supposed
> to be deleted?

That is true. However, if commit was False that object wouldn't be
deleted but it would still appear in the self.deleted_objects list. My
concern - or more accurately lack of understanding - is that the object
would remain in existence AND appear in the deleted list. This was
precisely what happened in my project and which I was trying to debug.

The symptom in the Admin was a checked box for deleting a child record
which stubbornly stayed there despite the Admin reporting a successful
save.

Mike

>
> -James
>
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users+unsubscribe@googlegroups.com
> <mailto:django-users+unsubscribe@googlegroups.com>.
> To post to this group, send email to django-users@googlegroups.com
> <mailto:django-users@googlegroups.com>.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/CA%2Be%2BciWaSsBQ-5EvhpkT0MJmcGM1KTt2y%2Bnw2BQ6p%2BHEUd8Rqg%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-users/CA%2Be%2BciWaSsBQ-5EvhpkT0MJmcGM1KTt2y%2Bnw2BQ6p%2BHEUd8Rqg%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/5677A9CD.6090303%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment