[Django] #27595: In admin panel, ForeignKey to model subclass using UUID as primary key is not automatically "selected"

169 views
Skip to first unread message

Django

unread,
Dec 13, 2016, 9:48:31 AM12/13/16
to django-...@googlegroups.com
#27595: In admin panel, ForeignKey to model subclass using UUID as primary key is
not automatically "selected"
-----------------------------------------+------------------------
Reporter: oyooyo | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | 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 |
-----------------------------------------+------------------------
Sample models.py:
{{{
from django.db import models

import uuid

class Base_Model(models.Model):
id = models.UUIDField(primary_key = True, default=uuid.uuid4,
editable=False)
# id = models.AutoField(primary_key = True)
prototype = models.ForeignKey('Prototype_Model', blank=True,
null=True)
def __str__(self):
return str(self.id)

class Prototype_Model(Base_Model):
pass
}}}

Sample admin.py:
{{{
from django.contrib import admin

from .models import Prototype_Model

class Base_Model_Admin(admin.ModelAdmin):
list_display = ['id', 'prototype']

admin.site.register(Prototype_Model, Base_Model_Admin)
}}}

Steps to reproduce:
1. Create a Prototype_Model via the admin. Leave the "prototype"
ForeignKey field empty.
2. Create another Prototype_Model via the admin. For the "prototype"
ForeignKey field, choose the first created Prototype_Model from the
dropdown
3. Switch to the Prototype_Model list view, it should show that the
"prototype" ForeignKey field of the second Prototype_Model indeed
references the first model
4. Click on this second Prototype_Model in order to access the change/edit
model form and look at the dropdown for the "prototype" field. The
expected behaviour is that the dropdown should have the referenced first
model automatically selected, but instead, nothing is automatically
selected.

**If an AutoField is used instead of a UUIDField as the primary key "id"
field (see commented out line in Base_Model), the behaviour is as
expected.**

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

Django

unread,
Dec 13, 2016, 2:44:04 PM12/13/16
to django-...@googlegroups.com
#27595: ForeignKey to model subclass using UUID as primary key isn't populated in
form's <select>
------------------------+------------------------------------
Reporter: oyooyo | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------+------------------------------------
Changes (by Tim Graham):

* type: Uncategorized => Bug
* component: Uncategorized => Forms
* stage: Unreviewed => Accepted


Comment:

I can reproduce this at `eb7fb565e6483637fc4ee251940b86db813485a0` on
SQLite but not PostgreSQL -- I guess it's based on whether or not the
database has a native UUID type. On SQLite, for example, the initial form
data appears as `{'prototype': '35bba53ceafc4df2b1abc110d5f51b2a'}` but
the UUID values in the form's `<select>` have dashes, so there's a
mismatch. On PostgreSQL, the initial data is `{'prototype': UUID
('154e323f-cc57-4399-9023-58357ae9ce21')}` and there's no issue.

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

Django

unread,
Jan 1, 2017, 2:54:55 PM1/1/17
to django-...@googlegroups.com
#27595: ForeignKey to model subclass using UUID as primary key isn't populated in
form's <select>
------------------------+-------------------------------------------
Reporter: oyooyo | Owner: Sarthak Mehrish
Type: Bug | Status: assigned

Component: Forms | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------+-------------------------------------------
Changes (by Sarthak Mehrish):

* owner: nobody => Sarthak Mehrish
* status: new => assigned


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

Django

unread,
Oct 18, 2018, 5:56:20 PM10/18/18
to django-...@googlegroups.com
#27595: ForeignKey to model subclass using UUID as primary key isn't populated in
form's <select>
------------------------+---------------------------------------
Reporter: oyooyo | Owner: Wayne Merry

Type: Bug | Status: assigned
Component: Forms | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------+---------------------------------------
Changes (by Wayne Merry):

* owner: Sarthak Mehrish => Wayne Merry


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

Django

unread,
Oct 18, 2018, 9:11:19 PM10/18/18
to django-...@googlegroups.com
#27595: ForeignKey to model subclass using UUID as primary key isn't populated in
form's <select>
------------------------+---------------------------------------
Reporter: oyooyo | Owner: Wayne Merry
Type: Bug | Status: assigned
Component: Forms | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------+---------------------------------------

Comment (by Wayne Merry):

A topic was posted to Django Developers regarding a UUID foreign key value
representation when using sqllite3. See
https://groups.google.com/forum/#!topic/django-developers/h46RAw67g_g

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

Django

unread,
Oct 18, 2018, 10:30:35 PM10/18/18
to django-...@googlegroups.com
#27595: ForeignKey to model subclass using UUID as primary key isn't populated in
form's <select>
-------------------------------------+-------------------------------------

Reporter: oyooyo | Owner: Wayne
| Merry
Type: Bug | Status: assigned
Component: Database layer | Version: 1.10
(models, ORM) |

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* component: Forms => Database layer (models, ORM)


Comment:

I feel like this isn't a form level issue from a bit of debugging locally.

I'm not sure what's going on here but somehow the database converters are
not considered for the foreign key. We've got tests for foreign key values
but I feel like the convoluted inheritance chain here as something to do
with the issue.

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

Django

unread,
Oct 18, 2018, 10:58:43 PM10/18/18
to django-...@googlegroups.com
#27595: Database converters are not run for related fields referencing related
fields

-------------------------------------+-------------------------------------
Reporter: oyooyo | Owner: Wayne
| Merry
Type: Bug | Status: assigned
Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

Alright so the underlying issue is the fact the `prototype` foreign key
point to `Prototype_Model`'s primary key which is a `OneToOneField`.

Somehow the related field chain is not followed along to determine the
non-related internal type and prevents the database converters from
correctly being chosen.

https://github.com/django/django/blob/084573c7156530047bec2c19e732423fa9d0ec13/django/db/backends/sqlite3/operations.py#L210-L220

It looks like most of the places that relies on `get_internal_type` could
be affected by that. Here's one example that works for one level
relationship chains but not for multiple ones

https://github.com/django/django/blob/084573c7156530047bec2c19e732423fa9d0ec13/django/db/backends/oracle/operations.py#L557

I think the solution here is to add a new `get_target_internal_type`
method on `ForeignKey` and along these lines

{{{#!python
def get_target_internal_type(self):
if isinstance(self.target, ForeignKey):
return self.target.get_target_internal_type()
return self.target.get_internal_type()
}}}

And audit the `get_internal_type()` usages to determine if they need to be
adjusted to call this method or not.

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

Django

unread,
Oct 19, 2018, 7:03:19 PM10/19/18
to django-...@googlegroups.com
#27595: Database converters are not run for related fields referencing related
fields
-------------------------------------+-------------------------------------
Reporter: oyooyo | Owner: Wayne
| Merry
Type: Bug | Status: assigned
Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Wayne Merry):

A PR has been made, but only for a test case that isolates this problem.
See https://github.com/django/django/pull/10538

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

Django

unread,
Oct 19, 2018, 7:12:03 PM10/19/18
to django-...@googlegroups.com
#27595: Database converters are not run for related fields referencing related
fields
-------------------------------------+-------------------------------------
Reporter: oyooyo | Owner: (none)
Type: Bug | Status: new

Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Wayne Merry):

* owner: Wayne Merry => (none)
* status: assigned => new


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

Django

unread,
Oct 20, 2018, 12:02:00 PM10/20/18
to django-...@googlegroups.com
#27595: Database converters are not run for related fields referencing related
fields
-------------------------------------+-------------------------------------
Reporter: oyooyo | Owner: (none)
Type: Bug | Status: new
Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

A minimal reproduction test as of 084573c7156530047bec2c19e732423fa9d0ec13
is

{{{
diff --git a/tests/model_fields/test_uuid.py
b/tests/model_fields/test_uuid.py
index bc1c8d5bc0..6b6af3ea7e 100644
--- a/tests/model_fields/test_uuid.py
+++ b/tests/model_fields/test_uuid.py
@@ -170,8 +170,12 @@ class TestAsPrimaryKey(TestCase):
self.assertEqual(r.uuid_fk, u2)

def test_two_level_foreign_keys(self):
+ gc = UUIDGrandchild()
# exercises ForeignKey.get_db_prep_value()
- UUIDGrandchild().save()
+ gc.save()
+ gc.refresh_from_db()
+ self.assertIsInstance(gc.uuidchild_ptr_id, uuid.UUID)
}}}

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

Django

unread,
Oct 20, 2018, 11:15:19 PM10/20/18
to django-...@googlegroups.com
#27595: Database converters are not run for related fields referencing related
fields
-------------------------------------+-------------------------------------
Reporter: oyooyo | Owner: (none)
Type: Bug | Status: new
Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

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

* has_patch: 0 => 1


Comment:

https://github.com/django/django/pull/10541

--
Ticket URL: <https://code.djangoproject.com/ticket/27595#comment:10>

Django

unread,
Oct 22, 2018, 11:22:57 AM10/22/18
to django-...@googlegroups.com
#27595: Database converters are not run for related fields referencing related
fields
-------------------------------------+-------------------------------------
Reporter: oyooyo | Owner: (none)
Type: Bug | Status: closed

Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

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

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


Comment:

Fixed by 5e3463f6bcec818431f0e1f4649d6a5bd944c459.

--
Ticket URL: <https://code.djangoproject.com/ticket/27595#comment:11>

Django

unread,
Oct 22, 2018, 2:56:47 PM10/22/18
to django-...@googlegroups.com
#27595: Database converters are not run for related fields referencing related
fields
-------------------------------------+-------------------------------------
Reporter: oyooyo | Owner: Tim
| Graham <timograham@…>

Type: Bug | Status: closed
Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

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

* owner: (none) => Tim Graham <timograham@…>


Comment:

In [changeset:"5e3463f6bcec818431f0e1f4649d6a5bd944c459" 5e3463f6]:
{{{
#!CommitTicketReference repository=""
revision="5e3463f6bcec818431f0e1f4649d6a5bd944c459"
Fixed #27595 -- Made ForeignKey.get_col() follow target chains.

Previously, foreign relationships were followed only one level deep which
prevents foreign keys to foreign keys from being resolved appropriately.
This was causing issues such as improper database value conversion for
UUIDField on SQLite because the resolved expression's output field's
internal type wasn't correct. Added tests to make sure unlikely foreign
reference cycles don't cause recursion errors.

Refs #24343.

Thanks oyooyo for the report and Wayne Merry for the investigation.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27595#comment:12>

Reply all
Reply to author
Forward
0 new messages