﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
15279	Inheritance of fields from a single abstract base class through multiple abstract classes causes errors.	Stephen Burrows	Stephen Burrows	"Assume the following models in `app`:

{{{#!python
from django.db import models


class Orange(models.Model):
    pass


class BaseClass(models.Model):
    field = models.ForeignKey(Orange)
    class Meta:
        abstract = True


class Parent1(BaseClass):
    class Meta:
        abstract=True


class Parent2(BaseClass):
    class Meta:
        abstract=True


class Child(Parent1, Parent2):
    pass
}}}

Currently, this definition will raise the following errors during model validation:

{{{#!sh
Unhandled exception in thread started by <bound method Command.inner_run of <django.core.management.commands.runserver.Command object at 0x101470490>>
Traceback (most recent call last):
  File ""..../django/core/management/commands/runserver.py"", line 88, in inner_run
    self.validate(display_num_errors=True)
  File ""..../django/core/management/base.py"", line 253, 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:
app.child: Accessor for field 'field' clashes with related field 'Orange.child_set'. Add a related_name argument to the definition for 'field'.
app.child: Accessor for field 'field' clashes with related field 'Orange.child_set'. Add a related_name argument to the definition for 'field'.
}}}

Using the {{{ %(app_label)s_%(class)s_related }}} syntax only makes things worse:

{{{
#!sh
Unhandled exception in thread started by <bound method Command.inner_run of <django.core.management.commands.runserver.Command object at 0x10146e4d0>>
Traceback (most recent call last):
  File ""..../django/core/management/commands/runserver.py"", line 88, in inner_run
    self.validate(display_num_errors=True)
  File ""..../django/core/management/base.py"", line 253, 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:
app.child: Accessor for field 'field' clashes with related field 'Orange.app_child_related'. Add a related_name argument to the definition for 'field'.
app.child: Reverse query name for field 'field' clashes with related field 'Orange.app_child_related'. Add a related_name argument to the definition for 'field'.
app.child: Accessor for field 'field' clashes with related field 'Orange.app_child_related'. Add a related_name argument to the definition for 'field'.
app.child: Reverse query name for field 'field' clashes with related field 'Orange.app_child_related'. Add a related_name argument to the definition for 'field'.
}}}

Instead of causing errors, it seems like the field should only be inherited  once from BaseClass. My patch handles this as follows: On each field instance, track the class it was originally declared for and the first non-abstract class that it shows up in. Then, when a field is being added to a class, check to make sure that it only gets added if it isn't a ""duplicate"". (The patch will incidentally also need to move the get_FIELD_display method declaration into cls._meta.add_field.)"	Bug	closed	Database layer (models, ORM)	dev	Normal	fixed	abstract inheritance	stephen.r.burrows@…	Accepted	1	0	0	1	0	0
