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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在抽象模型中的ManyToMany字段中设置related_name?相关的知识,希望对你有一定的参考价值。

我有这个抽象的模型:

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])
答案

你可以使用%(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 docs

注意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

另一答案

你只需要在这个属性中加一个字符串,用来指定SystemMessage.Also read in Django Docs中反向关系的名称。

试试这个:

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

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

以上是关于如何在抽象模型中的ManyToMany字段中设置related_name?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 会话模型中设置自定义字段?

根据来自另一个模型的异步查询在模型中设置虚拟字段

Wagtail:如何在管理员中设置计算字段(@property)标题

如何使用 on_delete 属性在用户模型的外键字段中设置用户全名?

在子类中设置超类字段

如何在Django Db记录中设置多个字段