如何在抽象模型的ManyToMany字段中设置related_name?

时间:2018-09-05 06:30:35

标签: python django inheritance django-models

我有这个抽象模型:

class HasSystemMessage(models.Model):
    class Meta:
        abstract = True

    messages = models.ManyToManyField(SystemMessage, related_name=?)

我将在至少三个其他模型(例如A,B和C)中使用此抽象模型。如何为这些类动态设置related_name?例如,对于B类,我希望related_name是Bs。有可能这样做吗?

为进一步阐明问题,这些类将如下所示:

class B(HasSystemMessage):
    # Some model fields 
class A(HasSystemMessage):
    # Some model fields

HasSystemMessage.objects.filter(a__contains=[some elements])

2 个答案:

答案 0 :(得分:1)

您可以使用%(class)s%(app_label)s

class HasSystemMessage(models.Model):
    class Meta:
        abstract = True

    messages = models.ManyToManyField(SystemMessage, related_name=%(app_label)s_%(class)s_related)

来自Django文档

  

在使用related_name和related_query_name时要小心¶   ForeignKey或ManyToManyField上的related_name或related_query_name,   您必须始终为该名称指定唯一的反向名称和查询名称   领域。通常,这会在抽象基类中引起问题,   因为该类的字段包含在每个孩子中   类,其属性值完全相同(包括   每次都有related_name和related_query_name。

     

要解决此问题,请在使用related_name或   抽象基类中的related_query_name(仅),部分值   应该包含“%(app_label)s”和“%(class)s”。

     

'%(class)s'替换为子类的小写名称   该字段用于其中。'%(app_label)s'被替换为   子类所在的应用的小写名称。每   安装的应用程序名称必须唯一,并且模型类名称   每个应用中的名称也必须是唯一的,因此生成的名称将   最终变得与众不同。

参考:https://docs.djangoproject.com/en/2.0/topics/db/models/#be-careful-with-related-name-and-related-query-name

答案 1 :(得分:0)

您只需要在此属性中放入一个字符串,即可指定与SystemMessageAlso read in Django Docs

反向关系的名称。

尝试一下:

class HasSystemMessage(models.Model):
class Meta:
    abstract = True

messages = models.ManyToManyField(SystemMessage, related_name='system_message')