[Django] #22850: False reverse accessor clash with inherited classes

14 views
Skip to first unread message

Django

unread,
Jun 16, 2014, 1:45:07 PM6/16/14
to django-...@googlegroups.com
#22850: False reverse accessor clash with inherited classes
----------------------------------------------+------------------------
Reporter: semenov | Owner: nobody
Type: Uncategorized | Status: new
Component: Database layer (models, ORM) | Version: 1.7-beta-2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+------------------------
Consider the following `models.py`:

{{{#!python
class Base(models.Model):
field1 = models.IntegerField()

class Derived(Base):
field2 = models.IntegerField()

class Pointer(models.Model):
base = models.ForeignKey(Base)
derived = models.ForeignKey(Derived)
}}}

it crashes:

{{{
Unhandled exception in thread started by <function wrapper at 0x105daab90>
Traceback (most recent call last):
File
"/Users/semenov/work/project/venv/src/django/django/utils/autoreload.py",
line 170, in wrapper
fn(*args, **kwargs)
File
"/Users/semenov/work/project/venv/src/django/django/core/management/commands/runserver.py",
line 104, in inner_run
self.validate(display_num_errors=True)
File
"/Users/semenov/work/project/venv/src/django/django/core/management/base.py",
line 361, in validate
return self.check(app_configs=app_configs,
display_num_errors=display_num_errors)
File
"/Users/semenov/work/project/venv/src/django/django/core/management/base.py",
line 413, in check
raise CommandError(msg)
django.core.management.base.CommandError: System check identified some
issues:

ERRORS:
project.Pointer.derived: (fields.E304) Reverse accessor for
'Pointer.derived' clashes with reverse accessor for 'Pointer.base'.
HINT: Add or change a related_name argument to the definition for
'Pointer.derived' or 'Pointer.base'.
}}}

However, if I rewrite it to the semantically equivalent form:

{{{#!python
class AbstractBase(models.Model):
field1 = models.IntegerField()
class Meta:
abstract = True

class Base(AbstractBase):
pass

class Derived(AbstractBase):
field2 = models.IntegerField()

class Pointer(models.Model):
base = models.ForeignKey(Base)
derived = models.ForeignKey(Derived)
}}}

it works fine.

'''EXPECTED RESULT''': both cases should work identically (create
identical database tables and ORM accessors).

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

Django

unread,
Jun 16, 2014, 7:51:17 PM6/16/14
to django-...@googlegroups.com
#22850: False reverse accessor clash with inherited classes
-------------------------------------+-------------------------------------

Reporter: semenov | Owner: nobody
Type: Uncategorized | Status: new
Component: Database layer | Version:
(models, ORM) | 1.7-beta-2
Severity: Normal | Resolution:
Keywords: | Triage Stage:
Has patch: 0 | Unreviewed
Needs tests: 0 | Needs documentation: 0
Easy pickings: 0 | Patch needs improvement: 0
| UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timo):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Comment:

Did the first version work in older versions of Django?

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

Django

unread,
Jun 17, 2014, 6:27:09 AM6/17/14
to django-...@googlegroups.com
#22850: False reverse accessor clash with inherited classes
-------------------------------------+-------------------------------------

Reporter: semenov | Owner: nobody
Type: Uncategorized | Status: new
Component: Database layer | Version: 1.4
(models, ORM) | Resolution:
Severity: Normal | Triage Stage:
Keywords: | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

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

* version: 1.7-beta-2 => 1.4


Comment:

I tested both cases on Django 1.4.X branch, the first version crashed with
similar error:

{{{
Unhandled exception in thread started by <bound method Command.inner_run
of <django.core.management.commands.runserver.Command object at
0x101e3b110>>


Traceback (most recent call last):

File "/Users/semenov/work/project/venv/lib/python2.7/site-
packages/django/core/management/commands/runserver.py", line 91, in
inner_run
self.validate(display_num_errors=True)
File "/Users/semenov/work/project/venv/lib/python2.7/site-
packages/django/core/management/base.py", line 270, in validate
raise CommandError("One or more models did not validate:\n%s" %
error_text)
django.core.management.base.CommandError: One or more models did not
validate:
project.pointer: Accessor for field 'derived' clashes with related field
'Derived.pointer_set'. Add a related_name argument to the definition for
'derived'.
}}}

The second version worked fine.

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

Django

unread,
Jul 28, 2014, 7:13:07 PM7/28/14
to django-...@googlegroups.com
#22850: False reverse accessor clash with inherited classes
-------------------------------------+-------------------------------------
Reporter: semenov | Owner: nobody
Type: Uncategorized | Status: closed

Component: Database layer | Version: 1.4
(models, ORM) | Resolution: invalid

Severity: Normal | Triage Stage:
Keywords: | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

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

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


Comment:

The two forms are really not equivalent -- they will created different
database tables. An explanation of the differences is
[https://docs.djangoproject.com/en/1.7/topics/db/models/#model-inheritance
here].

Having a ForeignKey to both Base and Derived in the first example in
really redundant as they will refer to the same database column
(`Base.id`). I believe that's the reason for the validation error.

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

Reply all
Reply to author
Forward
0 new messages