Skip to content

Instantly share code, notes, and snippets.

@melinath
Created February 7, 2011 22:05
Show Gist options
  • Save melinath/815337 to your computer and use it in GitHub Desktop.
Save melinath/815337 to your computer and use it in GitHub Desktop.
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
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index fd0a295..6bfdefe 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -234,6 +234,10 @@ class Field(object):
def contribute_to_class(self, cls, name):
self.set_attributes_from_name(name)
self.model = cls
+ if not hasattr(self, "_declared_on_class"):
+ self._declared_on_class = cls
+ if not hasattr(self, "_first_concrete_class") and not cls._meta.abstract:
+ self._first_concrete_class = cls
cls._meta.add_field(self)
if self.choices:
setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self))
diff --git a/django/db/models/options.py b/django/db/models/options.py
index 2f64c56..e6f286d 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -152,7 +152,16 @@ class Options(object):
# Insert the given field in the order in which it was created, using
# the "creation_counter" attribute of the field.
# Move many-to-many related fields from self.fields into
- # self.many_to_many.
+ # self.many_to_many. Ignore duplicate fields inherited from a
+ # single abstract base class.
+ try:
+ f = self.get_field(field.name)
+ except FieldDoesNotExist:
+ pass
+ else:
+ if f._declared_on_class == field._declared_on_class and getattr(f, '_first_concrete_class', None) == getattr(field, '_first_concrete_class', None):
+ return
+
if field.rel and isinstance(field.rel, ManyToManyRel):
self.local_many_to_many.insert(bisect(self.local_many_to_many, field), field)
if hasattr(self, '_m2m_cache'):
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'.
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'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment