带有索引、约束和权限的Django抽象模型:属性不由子类继承

2024-09-29 23:29:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Django3.2

我有以下型号:

app1

class IsPinnable(models.Model):
    is_pinned = models.BooleanField(default=False)
    pin_after_expiry_day_count = models.DurationField(default=0)    

    class Meta:
        abstract = True
        indexes = [
            models.Index(fields=['is_pinned' ]),
        ]
    


class IsModeratable(models.Model):
    approved = models.BooleanField(default=False)
    target_count_trigger = models.PositiveSmallIntegerField()
    positive_pass_count = models.PositiveSmallIntegerField(default=0)
    negative_pass_count = models.PositiveSmallIntegerField(default=0)
 
    # Other fields and methods ...

    def save(self, *args, **kwargs):
        # TODO: Sanity check on pass_count and trigger sizes
        # ...
        super().save(*args, **kwargs)


    class Meta:
        abstract = True
        permissions = (
                       ("moderate_item", "can moderate item"),
                       ("reset_moderation", "can (re)moderate a moderated item"),
                      )
        indexes = [
            models.Index(fields=['approved' ]),
        ]    

    class MyComponent(IsPinnable, IsModeratable):
        # some fields and methods ...

        class Meta(IsPinnable.Meta, IsModeratable.Meta):
            abstract = True
            
            # other stuff ...

app2

from app1.models import MyComponent

class Foo(MyComponent):
    # some fields and methods ...
    class Meta(MyComponent.Meta):
        abstract = False
   

现在,我知道抽象模型类不是在数据库中创建的——所以我最初希望Django在我尝试makemigrations时抛出一个异常——令我惊讶的是,我能够makemigrations&&migrate

然而,当我(通过psql)检查数据库时,我发现尽管表app2_foo具有它的父类中描述的所有字段,但索引并没有像the documentation所显示的那样从父类中进行

我缺少什么?我如何获得父类中定义的索引、约束和权限,以便传播到子类


Tags: andabstractfalsetruedefaultfieldsmodelscount
1条回答
网友
1楼 · 发布于 2024-09-29 23:29:09

这只是普通的类继承行为,以以下代码段为例:

class A:
    attr = [1]


class B:
    attr = [2]


class C(A, B):
    pass


print(C.attr) # Outputs: [1]

这是因为AMethod Resolution Order中位于B之前。如果假设C定义了attr = [3],那么输出应该是[3]

如果需要重写这些属性,可以在子类中执行类似操作:

class MyComponent(IsPinnable, IsModeratable):
    # some fields and methods ...
    
    class Meta(IsPinnable.Meta, IsModeratable.Meta):
        abstract = True
        indexes = [...] + IsPinnable.Meta.indexes + IsModeratable.Meta.indexes # explicitly assign the indexes here

Note: Although What you want can be made possible if Django decides to put that logic in the meta class (this is different from Meta here) of the Meta, but I believe that would then require much work on their end to merge such attributes and would be backwards incompatible and honestly would be a weird feature, what if one doesn't want those indexes?

相关问题 更多 >

    热门问题