You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django-rules配置抽象基类默认权限后抛出AttributeError报错

问题诱因

报错和分页逻辑无任何关联,分页文件只是第一个触发模型导入的入口,核心问题出在模型继承链与元类配置错误:

  1. 你定义的BaseModel仅继承了RulesModelBaseMixin,没有继承Django的models.Model,本身不属于合法Django模型,Django的模型元类不会为其初始化_meta属性
  2. 子类Ticket手动指定metaclass=RulesModelBase时,继承顺序存在问题:RulesModelBase执行权限挂载逻辑的时机早于Django模型元类初始化_meta的时机,尝试访问不存在的_meta属性就会抛出你看到的错误。

django-rules确实支持抽象基类配置默认权限,只是要求继承链和元类配置必须符合Django模型的初始化规则。

修复方案

按以下两步调整代码即可:

  1. 修正抽象基类的继承配置,基类必须同时继承RulesModelMixin和Django的models.Model,并指定元类为RulesModelBase:
from django.db import models
from rules.contrib.models import RulesModelMixin, RulesModelBase

# 保留你原有谓词定义:can_create_in_company、can_view_in_company、is_author、is_superuser

class BaseModel(RulesModelMixin, models.Model, metaclass=RulesModelBase):
    company_id = models.ForeignKey('company.Company', on_delete=models.CASCADE)
    created_by = models.ForeignKey(
        'user.User', on_delete=models.SET_NULL, null=True, blank=True)

    class Meta:
        abstract = True
        rules_permissions = {
            "can_create": can_create_in_company | is_superuser,
            "can_view": can_view_in_company | is_author | is_superuser
        }
  1. 子类继承时无需重复指定RulesModelMixin和RulesModelBase元类,直接继承BaseModel即可;需要覆盖权限时,在子类Meta中重写rules_permissions即可自动覆盖基类配置:
class Ticket(BaseModel):
    name = models.CharField(max_length=512, null=True, blank=True)

    # 按需覆盖/新增权限示例,不需要调整权限可省略该Meta配置
    class Meta(BaseModel.Meta):
        rules_permissions = {
            **BaseModel.Meta.rules_permissions,
            "can_edit": is_author | is_superuser  # 可新增权限,也可重写已有权限的规则
        }
注意事项
  • 所有继承BaseModel的子类都会自动继承基类配置的默认权限,无需重复配置
  • 如果子类需要完全重写权限,直接在自己的rules_permissions字典中定义全量权限即可,不需要继承基类的权限字典
  • Django模型的_meta属性由Django内置的ModelBase元类在类创建阶段生成,必须保证元类执行到django-rules的权限挂载逻辑前,_meta已经完成初始化,否则就会出现同类报错。

内容的提问来源于stack exchange,提问作者creyD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 14:06:22