#25363: Model fields pre_save not called if force_insert=True
-------------------------------------+-------------------------------------
Reporter: davidfischer-ch | Owner:
| davidfischer-ch
Type: Bug | Status: closed
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution: needsinfo
Keywords: pre_save,save | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by davidfischer-ch):
Hi akaariai,
Your mix-in is interesting but it has some issues, hopefully easy to fix.
1. This is actually broken by the `pre_save` logic for a simple reason :
The `pre_save` methods are called inside the save, a.k.a inside the
`super().save(...)` so your mix-in and my mix-in [https://github.com
/davidfischer-
ch/pytoolbox/blob/master/pytoolbox/django/models/mixins.py#L115
AutoUpdateFieldsMixin] will not detect those. Its a reason why I
implemented [https://github.com/davidfischer-
ch/pytoolbox/blob/master/pytoolbox/django/models/mixins.py#L153
CallFieldsPreSaveMixin].
I also implemented another mix-in (sometimes I feel like a DJ, doing many
mixes),[https://github.com/davidfischer-
ch/pytoolbox/blob/master/pytoolbox/django/models/mixins.py#L89
AutoRemovePKFromUpdateFieldsMixin] that will check if the primary key is
set to a new value, then the intention of the developer is probably to
duplicate the model by saving it with a new primary key. So the mix-in let
Django save with its own default options for save.
2. `__dict__.copy()` is not sufficient, if one of the fields, is, for
example, a `JSONField` then the content is a mutable type (`dict`). This
container may contains nested mutable types, and you have to `deepcopy` to
ensure your copy will reflect the unchanged data from the database and
will not be modified.
3. your overload of `save()` isn't generic enough to support all possible
arguments.
Interesting you saved the data in `_state`.
That's cleaner than my mix-in.
I am thinking loudly, but is it more performant that any field set by the
code should be updated regardless the value, something that will not
happen often, or is it better to check for diff. Checking for diff will
also double the memory usage for the data (is it any copy-on-write mix-in
out here?).
We also need to think about concurrent updates when designing a save-the-
changes mix-in. For that reason I implemented another mix-in
[https://github.com/davidfischer-
ch/pytoolbox/blob/master/pytoolbox/django/models/mixins.py#L243
UpdatePreconditionsMixin]. I don't know what is the best option, but maybe
its more explicit and intuitive that if the program sets the fields, that
they will be saved regardless the value.
Yes, many questions and thoughts.
I am eager to heard about you guys.
--
Ticket URL: <https://code.djangoproject.com/ticket/25363#comment:8>
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 unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/073.914a7fc2580f1fa3e489797dcd367a0c%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.