Opened 6 years ago
Closed 6 years ago
#30343 closed Bug (fixed)
Prefetch related is not working when used GFK for model that uses UUID field as PK.
Reported by: | Timur | Owned by: | Mariusz Felisiak |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | prefetch_related, UUID, generic foreign key |
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
How to reproduce:
- create model with UUID as primary key
class Foo(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) ...
- create another model with GFK to model Foo
class Bar(models.Model): foo_content_type = models.ForeignKey( ContentType, related_name='actor', on_delete=models.CASCADE, db_index=True ) foo_object_id = models.CharField(max_length=255, db_index=True) foo = GenericForeignKey('foo_content_type', 'foo_object_id') ...
- and try to get queryset with prefetch related (django orm engine return None for attribute foo):
Bar.objects.all().prefetch_related('foo')
Thanks a lot for your attention! Also i wanna point out some related bug report from third party library in which previously i faced with that issue, maybe it would useful – https://github.com/justquick/django-activity-stream/issues/245
Attachments (1)
Change History (10)
comment:1 by , 6 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Version: | 2.2 → master |
comment:2 by , 6 years ago
Resolution: | wontfix |
---|---|
Status: | closed → new |
Triage Stage: | Unreviewed → Accepted |
Sorry for previous comment.
This should work. Currently it works when foo_object_id
is an UUIDField
but doesn't work when it is a CharField
.
by , 6 years ago
Attachment: | 30343-test.diff added |
---|
comment:3 by , 6 years ago
IMO, adding get_prep_value()
to the UUIDField
should fix this issue 🤔:
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 2307dcae25..0a7a6b9736 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -2335,6 +2335,12 @@ class UUIDField(Field): return value return value.hex + def get_prep_value(self, value): + value = super().get_prep_value(value) + if value is None: + return None + return self.to_python(value) + def to_python(self, value): if value is not None and not isinstance(value, uuid.UUID): input_form = 'int' if isinstance(value, int) else 'hex'
comment:4 by , 6 years ago
Yeah that seems like the correct approach. I was about to suggest
-
django/contrib/contenttypes/fields.py
diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py index ed98ecb48c..6098b71a39 100644
a b class GenericForeignKey(FieldCacheMixin): 202 202 else: 203 203 model = self.get_content_type(id=ct_id, 204 204 using=obj._state.db).model_class() 205 return (model._meta.pk. get_prep_value(getattr(obj, self.fk_field)),205 return (model._meta.pk.to_python(getattr(obj, self.fk_field)), 206 206 model)
But it looks like this is really just an issue with UUIDField
.
comment:5 by , 6 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:8 by , 6 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Thanks for the report,
howeverGenericForeignKey
doesn't supportprefetch_related()
, from the same reason it doesn't not support alsofilter()
,exclude()
, etc. Please see documentation.