Opened 7 months ago
Last modified 7 months ago
#35434 closed Cleanup/optimization
prefetch_related_objects fails to cache UUID FKs when the string representation of a UUID is used — at Version 1
Reported by: | Selcuk Ayguney | Owned by: | nobody |
---|---|---|---|
Component: | Documentation | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Selcuk Ayguney, Simon Charette | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Consider the following models:
class Pet(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField(max_length=20) class Toy(models.Model): pet = models.ForeignKey(Pet, models.CASCADE, related_name="toys") name = models.CharField(max_length=20)
The following works and caches the deferred pet
instance as expected:
pet = Pet.objects.create(name="Fifi") toy_bone = Toy(pet_id=str(pet.id), name="Bone") print(toy_bone.pet)
It fails if prefetch_related_objects
is used:
pet = Pet.objects.create(name="Fifi") toy_bone = Toy(pet_id=str(pet.id), name="Bone") prefetch_related_objects([toy_bone], "pet") print(toy_bone.pet)
raise self.RelatedObjectDoesNotExist( ^^^^^^^^^^^^^^^^^ prefetch_related.models.Toy.pet.RelatedObjectDoesNotExist: Toy has no pet.
The behaviour is inconsistent as str to UUID conversion is automatically performed in the first example.
One may argue that the use of prefetch_related_objects
is redundant in this case. However, it is useful in async code where deferred lookups are not automatic.
Unit test to reproduce the issue:
https://github.com/django/django/pull/18132