{{{
controlled_entity_content_type = models.ForeignKey(ContentType,
blank=True, null=True, on_delete=models.CASCADE)
controlled_entity_object_id = models.PositiveIntegerField(blank=True,
null=True)
controlled_entity =
GenericForeignKey("controlled_entity_content_type",
"controlled_entity_object_id")
}}}
However, in unit-tests, when I refresh a user instance, the
controlled_entity relation isn't cleared from cache, as can be seen here
with IDs:
{{{
old_controlled_entity = authenticated_user.controlled_entity
authenticated_user.refresh_from_db()
new_controlled_entity = authenticated_user.controlled_entity
assert id(old_controlled_entity) != id(new_controlled_entity) #
FAILS
}}}
And this leads to subtle bugs like non-transitive equalities in tests :
{{{
assert authenticated_user.controlled_entity ==
fixtures.client1_project2_organization3
assert fixtures.client1_project2_organization3.get_pricing_plan()
== pricing_plan
assert authenticated_user.controlled_entity.get_pricing_plan() ==
pricing_plan # FAILS
}}}
Calling "authenticated_user.controlled_entity.refresh_from_db()" solevd
this particular bug, but "authenticated_user.refresh_from_db()" isn't
enough.
Tested under Django3.2.13 but the code of refresh_from_db() hasn't changed
since then in Git's main branch (except few cosmetic adjustments on code
format).
I'm a bit lost in the code of refresh_from_db(), but I've just seen that
the generic relation appears once in this loop, but is not considered as
"cached" in the if() branch.
{{{
for field in self._meta.related_objects:
#print("%% CLEARING RELATED FIELD", field)
if field.is_cached(self):
#print("%% DONE") # not called
field.delete_cached_value(self)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34137>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
Old description:
New description:
In my code, Users have a generic foreign key like so:
{{{
controlled_entity_content_type = models.ForeignKey(ContentType,
blank=True, null=True, on_delete=models.CASCADE)
controlled_entity_object_id = models.PositiveIntegerField(blank=True,
null=True)
controlled_entity =
GenericForeignKey("controlled_entity_content_type",
"controlled_entity_object_id")
}}}
However, in unit-tests, when I refresh a user instance, the
controlled_entity relation isn't cleared from cache, as can be seen here
with IDs:
{{{
old_controlled_entity = authenticated_user.controlled_entity
authenticated_user.refresh_from_db()
new_controlled_entity = authenticated_user.controlled_entity
assert id(old_controlled_entity) != id(new_controlled_entity) #
FAILS
}}}
And this leads to subtle bugs like non-transitive equalities in tests :
{{{
assert authenticated_user.controlled_entity ==
fixtures.client1_project2_organization3
assert fixtures.client1_project2_organization3.get_pricing_plan()
== pricing_plan
assert authenticated_user.controlled_entity.get_pricing_plan() ==
pricing_plan # FAILS
}}}
Calling "authenticated_user.controlled_entity.refresh_from_db()" solved
this particular bug, but "authenticated_user.refresh_from_db()" isn't
enough.
Tested under Django3.2.13 but the code of refresh_from_db() hasn't changed
since then in Git's main branch (except few cosmetic adjustments on code
format).
I'm a bit lost in the code of refresh_from_db(), but I've just seen that
the generic relation appears once in this loop, but is not considered as
"cached" in the if() branch.
{{{
for field in self._meta.related_objects:
#print("%% CLEARING RELATED FIELD", field)
if field.is_cached(self):
#print("%% DONE") # not called
field.delete_cached_value(self)
}}}
--
--
Ticket URL: <https://code.djangoproject.com/ticket/34137#comment:1>