#18627: Remove django-core uses of Model pre_init and post_init
-------------------------------------+-------------------------------------
Reporter: jdunck | Owner: jdunck
Type: | Status: assigned
Cleanup/optimization | Version: 1.4
Component: Database layer | Resolution:
(models, ORM) | Triage Stage: Accepted
Severity: Normal | Needs documentation: 0
Keywords: | Patch needs improvement: 0
Has patch: 1 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Comment (by aaugustin):
A quick summary of the context:
- `GenericForeignKey` uses `pre_init` since day 1, see [bca5327b21]. This
isn't rock-solid — for instance, setting a GFK to an unsaved model
instance doesn't work, even if you save the related model instance first
(there was a ticket about this recently).
- `ImageField` uses `post_init` since #11196, see [d89ba464dd]. That was
three years ago.
The proposed patch re-implements a signal-like pattern, but specific to
model fields. Through their `contribute_to_class` methods, fields can
register additional `pre_init` or `post_init` logic. Unlike the global
`pre_init` and `post_init` signals, this stays within each model's
boundaries, hence the speed optimization.
I'm moderately enthusiastic about this idea. Speeding-up model creation is
a worthy goal, but aren't we trading a short term benefit for more
technical debt? With this change, there will be two competing
`pre/post_init` mechanisms for models. Django (both core and contrib) will
user the faster one.
Do you plan to turn this into a public, documented API? The model API is a
foggy area: the docs encourage people to write their own fields (and we've
repeatedly waved off `JsonField` and `UuidField` for this reason) but they
don't describe very precisely what is kosher and what isn't. If we
introduce this mechanism, people will use it in their own fields. So we're
making this area even more difficult to clean up.
Have you tried to implement the parts of `GenericForeignKey` and
`ImageField` without relying on a model-level hook? Basically, the problem
is that a field must interact with other fields of the same model. It may
be possible to handle this within the field itself. I haven't said it's
easy, but if it was possible, it would be much cleaner, and probably safer
in the long term.
--
Ticket URL: <https://code.djangoproject.com/ticket/18627#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.