Ticket #15279: ticket15279_r15553.diff

File ticket15279_r15553.diff, 4.8 KB (added by melinath, 4 years ago)
  • django/db/models/fields/__init__.py

    diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
    index fd0a295..3eea553 100644
    a b class Field(object): 
    234234    def contribute_to_class(self, cls, name):
    235235        self.set_attributes_from_name(name)
    236236        self.model = cls
     237        if not hasattr(self, "_declared_on_class"):
     238            self._declared_on_class = cls
     239        if not hasattr(self, "_first_concrete_class") and not cls._meta.abstract:
     240            self._first_concrete_class = cls
    237241        cls._meta.add_field(self)
    238         if self.choices:
    239             setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self))
    240242
    241243    def get_attname(self):
    242244        return self.name
  • django/db/models/options.py

    diff --git a/django/db/models/options.py b/django/db/models/options.py
    index 10617dc..fe16663 100644
    a b from django.db.models.loading import get_models, app_cache_ready 
    1010from django.utils.translation import activate, deactivate_all, get_language, string_concat
    1111from django.utils.encoding import force_unicode, smart_str
    1212from django.utils.datastructures import SortedDict
     13from django.utils.functional import curry
    1314
    1415try:
    1516    all
    class Options(object): 
    6465        from django.db.backends.util import truncate_name
    6566
    6667        cls._meta = self
     68        self.model = cls
    6769        self.installed = re.sub('\.models$', '', cls.__module__) in settings.INSTALLED_APPS
    6870        # First, construct the default values for these options.
    6971        self.object_name = cls.__name__
    class Options(object): 
    158160        # Insert the given field in the order in which it was created, using
    159161        # the "creation_counter" attribute of the field.
    160162        # Move many-to-many related fields from self.fields into
    161         # self.many_to_many.
     163        # self.many_to_many. Ignore duplicate fields inherited from a
     164        # single abstract base class.
     165        try:
     166            f = self.get_field(field.name)
     167        except FieldDoesNotExist:
     168            pass
     169        else:
     170            if f._declared_on_class == field._declared_on_class and getattr(f, '_first_concrete_class', None) == getattr(field, '_first_concrete_class', None):
     171                return
     172
    162173        if field.rel and isinstance(field.rel, ManyToManyRel):
    163174            self.local_many_to_many.insert(bisect(self.local_many_to_many, field), field)
    164175            if hasattr(self, '_m2m_cache'):
    class Options(object): 
    173184        if hasattr(self, '_name_map'):
    174185            del self._name_map
    175186
     187        if field.choices:
     188            setattr(self.model, 'get_%s_display' % field.name, curry(self.model._get_FIELD_display, field=field))
     189
    176190    def add_virtual_field(self, field):
    177191        self.virtual_fields.append(field)
    178192
  • tests/modeltests/model_inheritance/models.py

    diff --git a/tests/modeltests/model_inheritance/models.py b/tests/modeltests/model_inheritance/models.py
    index a0fed8a..bbdbd37 100644
    a b class Comment(Attachment): 
    6464class Link(Attachment):
    6565    url = models.URLField()
    6666
     67class OrangeAttachment(Attachment):
     68    class Meta:
     69        abstract = True
     70
     71class BananaAttachment(Attachment):
     72    class Meta:
     73        abstract = True
     74
    6775#
    6876# Multi-table inheritance
    6977#
  • tests/modeltests/model_inheritance/tests.py

    diff --git a/tests/modeltests/model_inheritance/tests.py b/tests/modeltests/model_inheritance/tests.py
    index 334297a..bdcc28d 100644
    a b from django.core.exceptions import FieldError 
    44from django.test import TestCase
    55
    66from models import (Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place,
    7     Post, Restaurant, Student, StudentWorker, Supplier, Worker, MixinModel)
     7    Post, Restaurant, Student, StudentWorker, Supplier, Worker, MixinModel,
     8    OrangeAttachment, BananaAttachment)
    89
    910
    1011class ModelInheritanceTests(TestCase):
    class ModelInheritanceTests(TestCase): 
    6970            StudentWorker.objects.get, pk__lt=sw2.pk + 100
    7071        )
    7172
     73    def test_multiple_abstract_inheritance(self):
     74        # Define class here to avoid model validation errors while running tests.
     75        class SmoothieAttachment(OrangeAttachment, BananaAttachment):
     76            class Meta:
     77                app_label = 'model_inheritance'
     78
     79        # There should be no duplicate field names.
     80        field_names = [field.name for field in SmoothieAttachment._meta.fields]
     81        self.assertEqual(field_names.sort(), list(set(field_names)).sort())
     82
    7283    def test_multiple_table(self):
    7384        post = Post.objects.create(title="Lorem Ipsum")
    7485        # The Post model has distinct accessors for the Comment and Link models.
Back to Top