#28856: GenericForeignKey attributes create new instances on every access
------------------------------------------------+------------------------
Reporter: Morgan Wahl | Owner: nobody
Type: Bug | Status: new
Component: contrib.contenttypes | Version: 1.10
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------------+------------------------
Given these models:
{{{
class OtherSuper(models.Model):
pass
class OtherSub(OtherSuper):
pass
class Ref(models.Model):
obj_type = models.ForeignKey(ContentType, on_delete=models.PROTECT)
obj_id = models.CharField(max_length=255)
obj = GenericForeignKey('obj_type', 'obj_id')
}}}
I get this behavior:
{{{
In [1]: ref = Ref.objects.create(obj=OtherSub.objects.create())
In [2]: id(ref.obj) == id(ref.obj)
Out[2]: True
In [3]: ref.refresh_from_db()
In [4]: id(ref.obj) == id(ref.obj)
Out[4]: False
}}}
Each time `ref.obj` is accessed, a new instance is created for its value.
This is a problem, since doing something like `ref.obj.field = 1;
ref.obj.save()` won't actually update the field in the database. This only
happens when the referenced object is an instance of a model that
subclasses another model. (So, it wouldn't happen if referencing
`OtherSuper` in the models above.)
I've written a regression test against stable/1.10.x . I'll attach a
patch.
I discovered this because I have code that does the above (changes a field
on the related model and calls save). I call this a regression because it
works correctly on 1.9.
I'm not sure what the underly bug is; I looked at the diff in
`contenttypes` between 1.9 and 1.10, and there are more than a few
changes. Hopefully someone who understands the `GenericForeignKey`
implementation can figure this out.
--
Ticket URL: <https://code.djangoproject.com/ticket/28856>
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/053.16d3debf55c5df3424da86f273ac5af6%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.