Ticket #9638: app_label.2.patch

File app_label.2.patch, 7.2 KB (added by lakin@…, 15 years ago)

New patch with tests and documentation updates

  • django/db/models/fields/related.py

     
    9292            sup.contribute_to_class(cls, name)
    9393
    9494        if not cls._meta.abstract and self.rel.related_name:
    95             self.rel.related_name = self.rel.related_name % {'class': cls.__name__.lower()}
     95            self.rel.related_name = self.rel.related_name % {
     96                    'class': cls.__name__.lower(),
     97                    'app_label': cls._meta.app_label.lower(),
     98                    }
    9699
    97100        other = self.rel.to
    98101        if isinstance(other, basestring):
  • tests/modeltests/model_inheritance/models.py

     
    116116    def __unicode__(self):
    117117        return u"%s the parking lot" % self.name
    118118
     119#
     120# Abstract base classes with related models where the sub-class has the
     121# same name in a different app and inherits from the same abstract base
     122# class.
     123# NOTE: The actual API tests for the following classes are in
     124#       model_inheritance_same_model_name/models.py - They are defined
     125#       here in order to have the name conflict between apps
     126#
     127
     128class Title(models.Model):
     129    title = models.CharField(max_length=50)
     130
     131class NamedURL(models.Model):
     132    title = models.ForeignKey(Title, related_name='attached_%(app_label)s_%(class)s_set')
     133    url = models.URLField()
     134
     135    class Meta:
     136        abstract = True
     137
     138class Copy(NamedURL):
     139    content = models.TextField()
     140
     141    def __unicode__(self):
     142        return self.content
     143
    119144__test__ = {'API_TESTS':"""
    120145# The Student and Worker models both have 'name' and 'age' fields on them and
    121146# inherit the __unicode__() method, just as with normal Python subclassing.
  • tests/modeltests/model_inheritance_same_model_name/models.py

    Property changes on: tests/modeltests/model_inheritance_same_model_name/__init__.py
    ___________________________________________________________________
    Added: svn:eol-style
       + native
    
     
     1"""
     2XX. Model inheritance
     3
     4Model inheritance across apps can result in models with the same name resulting
     5in the need for an %(app_label)s format string. This app specifically tests
     6this feature by redefining the Copy model from model_inheritance/models.py
     7"""
     8
     9from django.db import models
     10from modeltests.model_inheritance.models import NamedURL, Title
     11
     12#
     13# Abstract base classes with related models
     14#
     15class Copy(NamedURL):
     16    content = models.TextField()
     17
     18    def __unicode__(self):
     19        return self.content
     20
     21
     22__test__ = {'API_TESTS':"""
     23# Create a Title
     24>>> title = Title(title='Lorem Ipsum')
     25>>> title.save()
     26
     27# The Title model has distinct accessors for both model_inheritance.Copy and
     28# model_inheritance_same_model_name.Copy models.
     29>>> title.attached_model_inheritance_copy_set.create(content='Save $ on V1agr@', url='http://v1agra.com/', title='V1agra is spam')
     30<Copy: Save $ on V1agr@>
     31>>> title.attached_model_inheritance_same_model_name_copy_set.create(content='The Web framework for perfectionists with deadlines.', url='http://www.djangoproject.com/', title='Django Rocks')
     32<Copy: The Web framework for perfectionists with deadlines.>
     33
     34# The Post model doesn't have an attribute called 'attached_%(app_label)s_%(class)s_set'.
     35>>> getattr(title, 'attached_%(app_label)s_%(class)s_set')
     36Traceback (most recent call last):
     37    ...
     38AttributeError: 'Title' object has no attribute 'attached_%(app_label)s_%(class)s_set'
     39
     40"""}
  • AUTHORS

    Property changes on: tests/modeltests/model_inheritance_same_model_name/models.py
    ___________________________________________________________________
    Added: svn:eol-style
       + native
    
     
    234234    David Krauth
    235235    kurtiss@meetro.com
    236236    Panos Laganakos <panos.laganakos@gmail.com>
    237     lakin.wecker@gmail.com
     237    Lakin Wecker <lakin.wecker@gmail.com> <lakin@structuredabstraction.com>
    238238    Nick Lane <nick.lane.au@gmail.com>
    239239    Stuart Langridge <http://www.kryogenix.org/>
    240240    Paul Lanier <planier@google.com>
  • docs/topics/db/models.txt

     
    858858the same values for the attributes (including :attr:`~django.db.models.ForeignKey.related_name`) each time.
    859859
    860860To work around this problem, when you are using :attr:`~django.db.models.ForeignKey.related_name` in an
    861 abstract base class (only), part of the name should be the string
    862 ``'%(class)s'``. This is replaced by the lower-cased name of the child class
    863 that the field is used in. Since each class has a different name, each related
    864 name will end up being different. For example::
    865 
     861abstract base class (only), part of the name should be contain
     862``'%(app_label)s'`` and ``'%(class)s'``. ``'%(class)s'`` is replaced by the lower-cased name of the child class
     863that the field is used in. ``'%(app_label)s'`` is replaced by the lower-cased name of the app the child class
     864is contained within.  Each installed application name must be unique and the model class names within each app
     865must also be unique, therefore the resulting name will end up being different.
     866For example, given an app ``common/models.py``::
    866867    class Base(models.Model):
    867         m2m = models.ManyToMany(OtherModel, related_name="%(class)s_related")
     868        m2m = models.ManyToMany(OtherModel, related_name="%(app_label)s_%(class)s_related")
    868869
    869870        class Meta:
    870871            abstract = True
     
    875876    class ChildB(Base):
    876877        pass
    877878
    878 The reverse name of the ``ChildA.m2m`` field will be ``childa_related``,
    879 whilst the reverse name of the ``ChildB.m2m`` field will be
    880 ``childb_related``. It is up to you how you use the ``'%(class)s'`` portion to
    881 construct your related name, but if you forget to use it, Django will raise
     879Along with another app ``rare/models.py``::
     880    from common.models import Base
     881
     882    class ChildB(Base):
     883        pass
     884
     885The reverse name of the ``commmon.ChildA.m2m`` field will be ``common_childa_related``,
     886whilst the reverse name of the ``common.ChildB.m2m`` field will be
     887``common_childb_related``, and finally the reverse name of the ``rare.ChildB.m2m`` field will be
     888``rare_childb_related``.  It is up to you how you use the ``'%(class)s'`` and ``'%(app_label)s``
     889portion to construct your related name, but if you forget to use it, Django will raise
    882890errors when you validate your models (or run :djadmin:`syncdb`).
    883891
    884892If you don't specify a :attr:`~django.db.models.ForeignKey.related_name` attribute for a field in an
Back to Top