#8070 closed Uncategorized (fixed)
related objects passed to model init are not cached/accessible
Reported by: | Gary Wilson | Owned by: | Gary Wilson |
---|---|---|---|
Component: | Core (Other) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Models:
from django.db import models class Color(models.Model): name = models.CharField(max_length=10) class Knight(models.Model): favorite = models.ForeignKey(Color)
Neither saved or unsaved related objects get cached:
# Unsaved object. >>> k = Knight(favorite=Color()) >>> hasattr(k, '_favorite_cache') False # Saved object. >>> k = Knight(favorite=Color.objects.create(name='blue')) >>> hasattr(k, '_favorite_cache') False # But assignment with saved or unsaved objects does cache correctly. >>> k = Knight() >>> k.favorite = Color() >>> hasattr(k, '_favorite_cache') True >>> k = Knight() >>> k.favorite = Color.objects.create(name='blue') >>> hasattr(k, '_favorite_cache') True
Also, in the saved related object case above, we do an extra query to refetch the object by id.
There's also a problem when trying to access the field when it was passed an unsaved object in the init:
# Unsaved object. >>> k = Knight(favorite=Color()) >>> k.favorite Traceback (most recent call last): ... DoesNotExist # Saved object. >>> k = Knight(favorite=Color.objects.create(name='blue')) >>> k.favorite <Color: blue>
The attached patch does both:
- Caches saved or unsaved related object passed to the Model init.
- Allows unsaved related objects to be accessed when they were passed to the Model init.
Attachments (2)
Change History (7)
by , 16 years ago
Attachment: | 8070.patch added |
---|
by , 16 years ago
Attachment: | 8070.2.patch added |
---|
comment:1 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Ready for checkin |
Someone else care to review?
comment:2 by , 16 years ago
Patch note: #6886 made the type checking happen on assignment, so we don't need to do the checking in the init anymore as long as you are setting using the attribute named by field.name
.
comment:3 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
(In [8185]) Fixed #8070 -- Cache related objects passed to Model init as keyword arguments. Also:
- Model init no longer performs a database query to refetch the related objects it is passed.
- Model init now caches unsaved related objects correctly, too. (Previously, accessing the field would raise
DoesNotExist
error fornull=False
fields.) - Added tests for assigning
None
tonull=True
ForeignKey
fields (refs #6886).
comment:5 by , 11 years ago
Easy pickings: | unset |
---|---|
Severity: | → Normal |
Type: | → Uncategorized |
UI/UX: | unset |
Allows unsaved related objects to be accessed when they were passed to the Model init.
Django accepted this but the relation wasn't saved, see #10811. I'm going to remove the test for that bug-prone behavior.
corrected a comment