微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有未继承约束的 Django 模型抽象模型:'constraints' 指的是字段 'xxx',它不是模型 'Foo' 的本地字段 myapp/models.py

如何解决带有未继承约束的 Django 模型抽象模型:'constraints' 指的是字段 'xxx',它不是模型 'Foo' 的本地字段 myapp/models.py

我使用的是 Django 3.2

我遇到了一个奇怪的行为,这似乎是一个错误; ABC 中定义的约束中使用的字段不会被子类继承。

myapp/models.py

class BaseFoo(models.Model):
    content_type = models.ForeignKey(ContentType,on_delete=models.CASCADE,related_name='%(class)s_content_type')
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type','object_id')
    user = models.ForeignKey(User,blank=False,null=False,related_name='%(class)s')
    created = models.DateTimeField(auto_Now_add=True)

    class Meta:
        abstract = True
        constraints = [
            models.UniqueConstraint(fields=['content_object','user'],name="'%(class)s_unique"),]
    
class Foo(BaseFoo):
    class Meta(BaseFoo.Meta):
        abstract = False

当我 makemigrations 时没问题,但是,当我尝试迁移架构 (`python manage.py migrate) 时,出现以下错误

myapp.Foo: (models.E016) 'constraints' 指的是字段 'content_object',它不是模型 'Foo' 的本地字段。 提示:这个问题可能是由多表继承引起的。

为什么 Foo 没有继承父 ABC 中明确定义的字段? - 我该如何解决这个问题(假设它不是错误)?

解决方法

1.您不能在 UniqueConstraint 中使用 GenericForeignKey,因为 GenericForeignKey 不是普通的字段对象。而在UniqueConstraint中使用content_typeobject_id,这相当于content_object


class Meta:
    abstract = True
    constraints = [
        models.UniqueConstraint(
            fields=['content_type','object_id','user'],name="%(app_label)s_%(class)s_user_unique"),]

Django Docs

由于 GenericForeignKey 的实现方式,您不能使用 这些字段直接带有过滤器(filter()exclude(),对于 示例)通过数据库 API。因为GenericForeignKey 不是普通的字段对象。

同样,GenericForeignKey 不会出现在 ModelForms 中。

2.根据抽象基类中的Django Docsrelated_name必须包含'%(app_label)s ' 和 '%(class)s'。并且您应该始终为字段指定唯一的反向名称和查询名称。

content_type = models.ForeignKey(
   ContentType,on_delete=models.CASCADE,related_name='%(app_label)s_%(class)s_content_types',related_query_name='%(app_label)s_%(class)s_content_type',)

user = models.ForeignKey(
    User,blank=False,null=False,related_name='%(app_label)s_%(class)s_users',related_query_name='%(app_label)s_%(class)s_user',)

如果您使用 related_namerelated_query_name ForeignKeyManyToManyField,您必须始终为字段指定唯一的反向名称和查询名称。这通常会 在抽象基类中引起问题,因为此字段上的字段 类包含在每个子类中,准确地 属性的相同值(包括 related_namerelated_query_name) 每次。

要解决此问题,当您使用 related_namerelated_query_name 在抽象基类中(仅),值的一部分 应包含“%(app_label)s”和“%(class)s”。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。