Django-rules配置抽象基类默认权限后抛出AttributeError报错
问题诱因
报错和分页逻辑无任何关联,分页文件只是第一个触发模型导入的入口,核心问题出在模型继承链与元类配置错误:
- 你定义的
BaseModel仅继承了RulesModelBaseMixin,没有继承Django的models.Model,本身不属于合法Django模型,Django的模型元类不会为其初始化_meta属性 - 子类
Ticket手动指定metaclass=RulesModelBase时,继承顺序存在问题:RulesModelBase执行权限挂载逻辑的时机早于Django模型元类初始化_meta的时机,尝试访问不存在的_meta属性就会抛出你看到的错误。
django-rules确实支持抽象基类配置默认权限,只是要求继承链和元类配置必须符合Django模型的初始化规则。
修复方案
按以下两步调整代码即可:
- 修正抽象基类的继承配置,基类必须同时继承
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 }
- 子类继承时无需重复指定
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
相关产品推荐
相关产品推荐

