[Django] #30343: Prefetch related is not working when used GFK for model that uses UUID field as PK.

16 views
Skip to first unread message

Django

unread,
Apr 9, 2019, 3:20:52 PM4/9/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: timur- | Owner: nobody
orudzhov |
Type: Bug | Status: new
Component: Database | Version: 2.2
layer (models, ORM) | Keywords: prefetch_related,
Severity: Normal | UUID, generic foreign key
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
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]

--
Ticket URL: <https://code.djangoproject.com/ticket/30343>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Apr 9, 2019, 5:49:24 PM4/9/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: timur-orudzhov | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: prefetch_related, | Triage Stage:
UUID, generic foreign key | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* status: new => closed
* version: 2.2 => master
* resolution: => wontfix


Comment:

Thanks for the report, however `GenericForeignKey` doesn't support
`prefetch_related()`, from the same reason it doesn't not support also
`filter()`, `exclude()`, etc. Please see
[https://docs.djangoproject.com/en/2.2/ref/contrib/contenttypes/#generic-
relations documentation]:
{{{
Due to the way GenericForeignKey is implemented, you cannot use such
fields directly with filters (filter() and exclude(), for example) via the
database API. Because a GenericForeignKey isn’t a normal field object,
these examples will not work:
...
}}}

Provided example works as expected with UUID PK, e.g.:
{{{
>>> for bar in Bar.objects.all():
... print(bar, bar.foo)
Bar object (4) Foo object (e6bdfd5e-51a8-49c7-9a7a-998452fad6aa)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:1>

Django

unread,
Apr 10, 2019, 1:16:51 AM4/10/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: timur-orudzhov | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: prefetch_related, | Triage Stage: Accepted
UUID, generic foreign key |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* status: closed => new
* resolution: wontfix =>
* stage: Unreviewed => Accepted


Comment:

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`.

--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:2>

Django

unread,
Apr 10, 2019, 1:18:05 AM4/10/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: timur-orudzhov | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: prefetch_related, | Triage Stage: Accepted
UUID, generic foreign key |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* Attachment "30343-test.diff" added.

Django

unread,
Apr 10, 2019, 1:26:32 AM4/10/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: timur-orudzhov | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: prefetch_related, | Triage Stage: Accepted
UUID, generic foreign key |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by felixxm):

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'
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:3>

Django

unread,
Apr 10, 2019, 1:37:49 AM4/10/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: timur-orudzhov | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: prefetch_related, | Triage Stage: Accepted
UUID, generic foreign key |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

Yeah that seems like the correct approach. I was about to suggest

{{{#!diff
diff --git a/django/contrib/contenttypes/fields.py
b/django/contrib/contenttypes/fields.py
index ed98ecb48c..6098b71a39 100644
--- a/django/contrib/contenttypes/fields.py
+++ b/django/contrib/contenttypes/fields.py
@@ -202,7 +202,7 @@ class GenericForeignKey(FieldCacheMixin):
else:
model = self.get_content_type(id=ct_id,
using=obj._state.db).model_class()
- return (model._meta.pk.get_prep_value(getattr(obj,
self.fk_field)),
+ return (model._meta.pk.to_python(getattr(obj,
self.fk_field)),
model)
}}}

But it looks like this is really just an issue with `UUIDField`.

--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:4>

Django

unread,
Apr 13, 2019, 5:56:19 AM4/13/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: Timur | Owner: felixxm
Type: Bug | Status: assigned

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: prefetch_related, | Triage Stage: Accepted
UUID, generic foreign key |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* owner: nobody => felixxm
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:5>

Django

unread,
Apr 13, 2019, 8:01:34 AM4/13/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: Timur | Owner: felixxm
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: prefetch_related, | Triage Stage: Accepted
UUID, generic foreign key |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* has_patch: 0 => 1


Comment:

[https://github.com/django/django/pull/11211 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:6>

Django

unread,
Apr 13, 2019, 10:25:05 AM4/13/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: Timur | Owner: felixxm
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: prefetch_related, | Triage Stage: Accepted
UUID, generic foreign key |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Timur):

Replying to [comment:6 felixxm]: Thanks for your work!
> [https://github.com/django/django/pull/11211 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:7>

Django

unread,
Apr 13, 2019, 11:05:57 PM4/13/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: Timur | Owner: felixxm
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: prefetch_related, | Triage Stage: Ready for
UUID, generic foreign key | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:8>

Django

unread,
Apr 14, 2019, 4:03:27 AM4/14/19
to django-...@googlegroups.com
#30343: Prefetch related is not working when used GFK for model that uses UUID
field as PK.
-------------------------------------+-------------------------------------
Reporter: Timur | Owner: felixxm
Type: Bug | Status: closed

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution: fixed

Keywords: prefetch_related, | Triage Stage: Ready for
UUID, generic foreign key | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by GitHub <noreply@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"1afbc96a75bd1765a56054f57ea2d4b238af3f4d" 1afbc96]:
{{{
#!CommitTicketReference repository=""
revision="1afbc96a75bd1765a56054f57ea2d4b238af3f4d"
Fixed #30343 -- Fixed prefetch_related() for GenericForeignKey when PK of
related field is UUIDField.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/30343#comment:9>

Reply all
Reply to author
Forward
0 new messages