#27065 closed Bug (invalid)
Deferred fields not passed to inherited models' __class__.__dict__
Reported by: | Jarek Glowacki | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.10 |
Severity: | Normal | Keywords: | defer only inherited DeferredAttribute |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Possibly a regression, possibly me misunderstanding how this should now work in 1.10.
class A(models.Model): name = models.CharField(max_length=20) addy = models.CharField(max_length=200) class B(A): name2 = models.CharField(max_length=20)
Calling:
b = B.objects.only('name').first()
we expect name2
and addy
to get deferred. Calling b.get_deferred_fields()
, we get both these field names returned as expected.
However, inspecting b.__class__.__dict__
, we see that only the DeferredAttribute
for name2
is available. To get the one for addy
, we need to consult b
's parent. This was not the case in 1.9.
See my PR to django-model-utils for context.
Change History (2)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Keywords: | only DeferredAttribute added |
---|---|
Resolution: | → invalid |
Status: | new → closed |
Thanks, I've verified it's definitely commit 7f51876f99851fdc3fef63aecdfbcffa199c26b9 that causes this change in behaviour.
DeferredAttribute
instances inherited from parent models can no longer be obtained through instance.__class__.__dict__
because the class is no longer dynamically created, but rather has the DeferredAttribute
instances stapled on with setattr
.
However, thanks to this change, a handle to the DeferredAttribute
descriptor can be obtained by accessing the field directly from the instance's class, which looks considerably nicer and does pull through inherited fields.
So
deferred_field = instance.__class__.__dict__.get(field_name) # pre dj110
becomes
deferred_field = getattr(instance.__class__, field_name) # dj110+
I guess it can't hurt mentioning this in the release notes, though at the same time I don't see particularly many projects that would need to handle the DeferredAttribute
descriptors directly. You're in a better position to make that call. At the very least this ticket can serve as an answer to people who google this problem.
Closing.
I'd guess 7f51876f99851fdc3fef63aecdfbcffa199c26b9 is the commit in question. Can you come up with a test case that demonstrates a bug in normal Django usage? If not, that change sounds like an implementation detail. We might mention it in the release notes if you feel it might affect other projects.