[Django] #26186: When extending from abstract model, ForeignKey points to wrong application

14 views
Skip to first unread message

Django

unread,
Feb 8, 2016, 1:19:41 PM2/8/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
----------------------------------------------+--------------------
Reporter: skyjur | Owner: nobody
Type: Bug | Status: new
Component: Database layer (models, ORM) | Version: 1.9
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+--------------------
This might be related to https://code.djangoproject.com/ticket/25858

I have following code:

'''app_A/models.py:'''

{{{
class AbstractModel1(Model):
class Meta:
abstract = True


class AbstractModel2(Model):
model1 = ForeignKey('Model1')

class Meta:
abstract = True


class Model1(AbstractModel1):
pass

class Model2(AbstractModel12):
pass
}}}


'''app_B/models.py:'''


{{{
from app_A.models import AbstractModel1, AbstractModel2

class Model1(AbstractModel1):
pass

class Model2(AbstractModel12):
pass
}}}

in Django 1.8, the `app_B.Model2.model1` would point to `app_B.Model1`,
but in Django 1.9.2 it points to `app_A.Model1` so my code no longer
works.

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

Django

unread,
Feb 9, 2016, 12:33:03 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by charettes):

* status: new => closed
* needs_better_patch: => 0
* resolution: => invalid
* needs_tests: => 0
* needs_docs: => 0


Comment:

Hi skyjur,

While I can reproduce on Django 1.9 and 1.9.1 (where it was considered a
regression #25858) I cannot reproduce on any version of Django 1.8.

I even tried swapping the order of `'app_A'` and `'app_B'` in
`INSTALLED_APPS` with no success.

You can find the test applications I used in my attempts to reproduce
[https://github.com/charettes/django-
ticketing/commit/d293d7cfcb8ba72dc1ebb0c0c7645af83339fa34 here].

Are you sure you managed to reproduce against Django 1.8? If it's the case
please reopen this ticket with more details.

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

Django

unread,
Feb 9, 2016, 1:21:58 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: nobody

Type: Bug | Status: closed
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by skyjur):

I have updated your test case:
https://github.com/charettes/django-ticketing/pull/1

In my app my abstract models are defined in `a/abstract.py` and then
imported into `a/models.py`, I didn't realise this was important.

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

Django

unread,
Feb 9, 2016, 1:26:27 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------

Reporter: skyjur | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by skyjur):

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


Old description:

> This might be related to https://code.djangoproject.com/ticket/25858
>
> I have following code:
>
> '''app_A/models.py:'''
>
> {{{
> class AbstractModel1(Model):
> class Meta:
> abstract = True
>

> class AbstractModel2(Model):
> model1 = ForeignKey('Model1')
>
> class Meta:
> abstract = True
>

> class Model1(AbstractModel1):
> pass
>
> class Model2(AbstractModel12):
> pass
> }}}
>

> '''app_B/models.py:'''
>

> {{{
> from app_A.models import AbstractModel1, AbstractModel2
>
> class Model1(AbstractModel1):
> pass
>
> class Model2(AbstractModel12):
> pass
> }}}
>
> in Django 1.8, the `app_B.Model2.model1` would point to `app_B.Model1`,
> but in Django 1.9.2 it points to `app_A.Model1` so my code no longer
> works.

New description:

I have following code:

'''app_A/models.py:'''

{{{
class AbstractModel1(Model):
class Meta:
abstract = True


class AbstractModel2(Model):
model1 = ForeignKey('Model1')

class Meta:
abstract = True
}}}

'''app_A/models.py:'''

{{{
from .abstract import AbstractModel1, AbstractModel12

class Model1(AbstractModel1):
pass

class Model2(AbstractModel12):
pass
}}}


'''app_B/models.py:'''


{{{
from app_A.abstract import AbstractModel1, AbstractModel2

class Model1(AbstractModel1):
pass

class Model2(AbstractModel12):
pass
}}}

in Django 1.8, the `app_B.Model2.model1` would point to `app_B.Model1`,
but in Django 1.9.2 it points to `app_A.Model1` so my code no longer
works.


Test case can be found: https://github.com/skyjur/django-
ticketing/tree/master/ticket_26186

--

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

Django

unread,
Feb 9, 2016, 1:27:23 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------

Reporter: skyjur | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by skyjur:

Old description:

> This might be related to https://code.djangoproject.com/ticket/25858
>
> I have following code:
>
> '''app_A/models.py:'''
>
> {{{
> class AbstractModel1(Model):
> class Meta:
> abstract = True
>

> class AbstractModel2(Model):
> model1 = ForeignKey('Model1')
>
> class Meta:
> abstract = True
> }}}
>

> '''app_A/models.py:'''
>
> {{{
> from .abstract import AbstractModel1, AbstractModel12
>

> class Model1(AbstractModel1):
> pass
>
> class Model2(AbstractModel12):
> pass
> }}}
>

> '''app_B/models.py:'''
>

> {{{
> from app_A.abstract import AbstractModel1, AbstractModel2


>
> class Model1(AbstractModel1):
> pass
>
> class Model2(AbstractModel12):
> pass
> }}}
>
> in Django 1.8, the `app_B.Model2.model1` would point to `app_B.Model1`,
> but in Django 1.9.2 it points to `app_A.Model1` so my code no longer
> works.
>

> Test case can be found: https://github.com/skyjur/django-
> ticketing/tree/master/ticket_26186

New description:

I have following code:

'''app_A/abstract.py:'''

{{{
class AbstractModel1(Model):
class Meta:
abstract = True


class AbstractModel2(Model):
model1 = ForeignKey('Model1')

class Meta:
abstract = True
}}}

'''app_A/models.py:'''

{{{
from .abstract import AbstractModel1, AbstractModel12

class Model1(AbstractModel1):
pass

class Model2(AbstractModel12):
pass
}}}


'''app_B/models.py:'''


{{{
from app_A.abstract import AbstractModel1, AbstractModel2

class Model1(AbstractModel1):
pass

class Model2(AbstractModel12):
pass
}}}

in Django 1.8, the `app_B.Model2.model1` would point to `app_B.Model1`,
but in Django 1.9.2 it points to `app_A.Model1` so my code no longer
works.

Test case can be found: https://github.com/skyjur/django-
ticketing/tree/master/ticket_26186

--

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

Django

unread,
Feb 9, 2016, 1:39:24 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------

Reporter: skyjur | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by skyjur):

I have added another test case showing that in 1.9 it's impossible to
extend from abstract models if they contain foreign keys to abstract model
that is not inside an installed app.

In 1.8 this was possible:

https://github.com/skyjur/django-ticketing/tree/master/ticket_26186_2

tox output:

{{{
django189 runtests: commands[0] | django-admin test
Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
Destroying test database for alias 'default'...
django192 runtests: commands[0] | django-admin test
Creating test database for alias 'default'...
Traceback (most recent call last):
<...>
self._related_fields = self.resolve_related_fields()
File "django-ticketing/ticket_26186/.tox/django192/local/lib/python2.7
/site-packages/django/db/models/fields/related.py", line 567, in
resolve_related_fields
raise ValueError('Related model %r cannot be resolved' %
self.remote_field.model)
ValueError: Related model u'None.Model1' cannot be resolved
ERROR: InvocationError: 'django-
ticketing/ticket_26186_2/.tox/django192/bin/django-admin test'
ERROR: InvocationError: 'django-
ticketing/ticket_26186_2/.tox/django192/bin/django-admin test'
______________summary__________________________ __________
django189: commands succeeded
ERROR: django192: commands failed
}}}

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

Django

unread,
Feb 9, 2016, 1:44:13 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------

Reporter: skyjur | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by timgraham):

Does it raise a deprecation warning in 1.8? There was a deprecation that
ended in 1.9that may be relevant -- from the release notes: "All models
need to be defined inside an installed application or declare an explicit
`app_label`." To confirm this, can you bisect to the commit in Django
where the behavior changed?

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

Django

unread,
Feb 9, 2016, 3:09:20 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------

Reporter: skyjur | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by charettes):

In your example both `app_B.Model2.model1` and `app_A.Model2.model1` are
pointing to `app_B.Model1` because `app_B`'s models module was imported
first (because of the order of `INSTALLED_APPS`) and triggered the import
of `app_A.abstract`.

No version of Django allowed you to make `Model2` point to their
respective `Model1`. The only thing that changed in Django 1.9.2 is that
lazy related references defined on abstract models are now bound to the
application in which they are defined.

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

Django

unread,
Feb 9, 2016, 3:48:17 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: charettes
Type: Bug | Status: assigned

Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | 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 charettes):

* status: new => assigned
* owner: nobody => charettes
* severity: Normal => Release blocker
* stage: Unreviewed => Accepted


Comment:

Well I stand corrected. It looks like the reported behavior is possible as
long as the application containing the abstract module is not yet
imported.

Here's what happens on '''Django 1.8'''.

The `b` application is imported by the app loading mechanism and triggers
and the import of `a.abstract`. At this point the abstract models are not
bound to any application and thus the `AbstractModel2.model1` field is not
resolved to any model which allows the `b.Model2.model1` field to resolves
to `b.Model1`. When the `a` application is loaded the abstract models are
bound to it (because they are defined in a `a` submodule) and thus
`a.Model2` automatically resolves to `a.Model1`.

In this case if the `a` application is loaded before the `b` application
`b.Model2` will point to `a.Model1` because the abstract models were bound
to the `a` application when `b.models` will import `a.abstract` (which was
imported by `a.models` first).

Here's what happen before #25858 was fixed ('''1.9, 1.9.1'''):

App relative lazy relationships defined on abstract models were never
resolved thus the behavior described above if the `b` application appeared
before the `a` one on Django `1.8` was always present and not dependent on
`ÌNSTALLED_APPS` ordering.

Here's what happen since #25858 is fixed ('''1.9.2''' , '''master'''):

It's not possible anymore as app relative lazy relationships defined on
abstract models are bound to the application in which they are defined.

I'll take this to the ML again to gather feedback but I'm inclined to
close this as ''wontfix'' because the behavior was only achievable in 1.8
through import side effects.

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

Django

unread,
Feb 9, 2016, 4:36:17 PM2/9/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: charettes
Type: Bug | Status: assigned
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | 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 charettes):

Posted to the [https://groups.google.com/d/msg/django-
developers/jRut8aYEet0/xmwmFk3sCAAJ mailing list].

I suggested we revert the fix for #25858 and instead document how app
relative relationships defined on
abstract models are resolved.

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

Django

unread,
Feb 22, 2016, 4:57:28 PM2/22/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: charettes
Type: Bug | Status: assigned
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | 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 charettes):

* has_patch: 0 => 1


Comment:

Here's a [https://github.com/django/django/pull/6178 PR] with the
suggested changes.

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

Django

unread,
Feb 24, 2016, 2:26:15 PM2/24/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: charettes
Type: Bug | Status: assigned
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1


Comment:

Left comments for improvement.

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

Django

unread,
Feb 29, 2016, 1:55:58 PM2/29/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: charettes
Type: Bug | Status: assigned
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | 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 charettes):

* needs_better_patch: 1 => 0


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

Django

unread,
Feb 29, 2016, 8:04:55 PM2/29/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: charettes
Type: Bug | Status: assigned
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Ready for
| checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/26186#comment:13>

Django

unread,
Feb 29, 2016, 10:08:15 PM2/29/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: charettes
Type: Bug | Status: closed

Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | Resolution: fixed

Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette <charette.s@…>):

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


Comment:

In [changeset:"0223e213dd690b6b6e0669f836a20efb10998c83" 0223e213]:
{{{
#!CommitTicketReference repository=""
revision="0223e213dd690b6b6e0669f836a20efb10998c83"
Fixed #26186 -- Documented how app relative relationships of abstract
models behave.

This partially reverts commit bc7d201bdbaeac14a49f51a9ef292d6312b4c45e.

Thanks Tim for the review.

Refs #25858.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/26186#comment:14>

Django

unread,
Feb 29, 2016, 10:15:24 PM2/29/16
to django-...@googlegroups.com
#26186: When extending from abstract model, ForeignKey points to wrong application
-------------------------------------+-------------------------------------
Reporter: skyjur | Owner: charettes
Type: Bug | Status: closed
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette <charette.s@…>):

In [changeset:"48cf7516409c668bf11e24e6b7cd8eaea13ae3b8" 48cf7516]:
{{{
#!CommitTicketReference repository=""
revision="48cf7516409c668bf11e24e6b7cd8eaea13ae3b8"
[1.9.x] Fixed #26186 -- Documented how app relative relationships of
abstract models behave.

This partially reverts commit bc7d201bdbaeac14a49f51a9ef292d6312b4c45e.

Thanks Tim for the review.

Refs #25858.

Backport of 0223e213dd690b6b6e0669f836a20efb10998c83 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/26186#comment:15>

Reply all
Reply to author
Forward
0 new messages