django知識點: related_name, related_query_name 的使用

Be careful with related_name and related_query_name

If you are using related_name or related_query_name on a ForeignKey or ManyToManyField, you must always specify a unique reverse name and query name for the field. This would normally cause a problem in abstract base classes, since the fields on this class are included into each of the child classes, with exactly the same values for the attributes (including related_name and related_query_name) each time.

To work around this problem, when you are using related_name or related_query_name in an abstract base class (only), part of the value should contain '%(app_label)s' and '%(class)s'.

  • '%(class)s' is replaced by the lowercased name of the child class that the field is used in.
  • '%(app_label)s' is replaced by the lowercased name of the app the child class is contained within. Each installed application name must be unique and the model class names within each app must also be unique, therefore the resulting name will end up being different.

For example, given an app common/models.py:

from django.db import models

class Base(models.Model):
    m2m = models.ManyToManyField(
        OtherModel,
        related_name="%(app_label)s_%(class)s_related",
        related_query_name="%(app_label)s_%(class)ss",
    )

    class Meta:
        abstract = True

class ChildA(Base):
    pass

class ChildB(Base):
    pass

Along with another app rare/models.py:

from common.models import Base

class ChildB(Base):
    pass

The reverse name of the common.ChildA.m2m field will be common_childa_related and the reverse query name will be common_childas. The reverse name of the common.ChildB.m2m field will be common_childb_related and the reverse query name will be common_childbs. Finally, the reverse name of the rare.ChildB.m2m field will be rare_childb_related and the reverse query name will be rare_childbs. It’s up to you how you use the '%(class)s' and '%(app_label)s' portion to construct your related name or related query name but if you forget to use it, Django will raise errors when you perform system checks (or run migrate).

If you don’t specify a related_name attribute for a field in an abstract base class, the default reverse name will be the name of the child class followed by '_set', just as it normally would be if you’d declared the field directly on the child class. For example, in the above code, if the related_name attribute was omitted, the reverse name for the m2m field would be childa_set in the ChildA case and childb_set for the ChildB field.

 

總結: 相對來講,自設定的優勢更好!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章