Django

Code

Changeset 7432

Show
Ignore:
Timestamp:
04/16/08 03:09:46 (3 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Added a way to specify the related_name attribute on
abstract base classes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/db/models/fields/related.py

    r7396 r7432  
     1import copy 
     2 
    13from django.db import connection, transaction 
    24from django.db.models import signals, get_model 
     
    109111        else: 
    110112            self.do_related_class(other, cls) 
     113        if not cls._meta.abstract and self.rel.related_name: 
     114            self.rel.related_name = self.rel.related_name % {'class': cls.__name__.lower()} 
    111115 
    112116    def set_attributes_from_rel(self): 
     
    150154 
    151155    def _get_related_query_name(self, opts): 
    152         # This method defines the name that can be used to identify this related object 
    153         # in a table-spanning query. It uses the lower-cased object_name by default, 
    154         # but this can be overridden with the "related_name" option. 
     156        # This method defines the name that can be used to identify this 
     157        # related object in a table-spanning query. It uses the lower-cased 
     158        # object_name by default, but this can be overridden with the 
     159        # "related_name" option. 
    155160        return self.rel.related_name or opts.object_name.lower() 
    156161 
  • django/branches/queryset-refactor/docs/model-api.txt

    r7341 r7432  
    887887                             explanation and example. 
    888888 
     889                             If using this in an `abstract base class`_, be 
     890                             sure to read the `extra notes`_ in that section 
     891                             about ``related_name``. 
     892 
    889893    ``to_field``             The field on the related object that the relation 
    890894                             is to. By default, Django uses the primary key of 
     
    894898.. _`Database API reference`: ../db-api/ 
    895899.. _related objects documentation: ../db-api/#related-objects 
     900.. _abstract base class: `Abstract base classes`_ 
     901.. _extra notes: `Be careful with related_name`_ 
    896902 
    897903Many-to-many relationships 
     
    21472153the same database table, which is almost certainly not what you want. 
    21482154 
     2155Be careful with ``related_name`` 
     2156~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     2157 
     2158If you are using the ``related_name`` attribute on a ``ForeignKey`` or 
     2159``ManyToManyField``, you must always specify a *unique* reverse name for the 
     2160field. This would normally cause a problem in abstract base classes, since the 
     2161fields on this class are included into each of the child classes, with exactly 
     2162the same values for the attributes (including ``related_name``) each time. 
     2163 
     2164To work around this problem, when you are using ``related_name`` in an 
     2165abstract base class (only), part of the name should be the string 
     2166``'%(class)s'``. This is replaced by the lower-cased name of the child class 
     2167that the field is used in. Since each class has a different name, each related 
     2168name will end up being different. For example:: 
     2169 
     2170    class Base(models.Model): 
     2171        m2m = models.ManyToMany(OtherModel, related_name="%(class)s_related") 
     2172 
     2173        class Meta: 
     2174            abstract = True 
     2175 
     2176    class ChildA(Base): 
     2177        pass 
     2178 
     2179    class ChildB(Base): 
     2180        pass 
     2181 
     2182The reverse name of the ``ChildA.m2m`` field will be ``childa_related``, 
     2183whilst the reverse name of the ``ChildB.m2m`` field will be 
     2184``childb_related``. It is up to you how you use the ``'%(class)s'`` portion to 
     2185construct your related name, but if you forget to use it, Django will raise 
     2186errors when you validate your models (or run ``syncdb``). 
     2187 
    21492188Multi-table inheritance 
    21502189-----------------------