#27340 closed New feature (needsinfo)
Model pre_init signal should provide an `instance` argument
Reported by: | Ask Solem Hoel | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.10 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I struggle to find reasons as to why this argument is ommitted.
The current signature for pre_init is:
class Model(six.with_metaclass(ModelBase)): _deferred = False def __init__(self, *args, **kwargs): signals.pre_init.send(sender=self.__class__, args=args, kwargs=kwargs)
I suggest that the signature should be:
class Model(six.with_metaclass(ModelBase)): _deferred = False def __init__(self, *args, **kwargs): signals.pre_init.send(sender=self.__class__, args=args, kwargs=kwargs, instance=self)
Or alternatively, that the post_init
signal contains the args and kwargs used to construct the model.
The reason for wanting access to the instance in pre_init is that I want to track changes
to the model since it was first retrieved from the database - This is currently not possible without subclassing Model,
and that is not a realistic option for us as we deal with third party models.
The current way we handle this is by using pre_save
to fetch the row from the database again, but this is suboptimal
and this a simple change would allow us to do this.
Change History (4)
comment:1 by , 8 years ago
Component: | Uncategorized → Database layer (models, ORM) |
---|---|
Type: | Uncategorized → New feature |
comment:2 by , 8 years ago
comment:3 by , 8 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
comment:4 by , 8 years ago
lol, you want an example. Brace yourself, will probably be more difficult to understand, but here:
https://github.com/robinhood/thorn/blob/master/thorn/django/signals.py#L39-L44
we use the pre)save signal to store a snapshot of how the model looked like before it was changed
With the proposed change we'd be able to avoid doing two database queries for every Model.save by doing this:
@signals.pre_init.connect
def _track_changes(instance, args, kwargs, kwargs):
instance._original_args = args, kwargs
There's no other way as far as I can find, as we don't want to monkeypatch Model, and in any case it's very strange that the pre_init signal omits the instance being created.
Could you provide an example of your existing code and what it would look like after this change? I'll check that I don't see another way to accomplish your use case.