DJANGO与抽象基类投掷错误后添加后的规则
将django-rules
添加到我的django项目中,我遇到以下问题:我想在我的抽象基类中添加默认权限,并在需要时覆盖它们。在基类和继承类的示例下:
class BaseModel(RulesModelBaseMixin):
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
}
class Ticket(RulesModelMixin, BaseModel, metaclass=RulesModelBase):
name = models.CharField(max_length=512, null=True, blank=True)
添加此抽象基类后,有一个看似无关的错误消息:
Traceback (most recent call last):
File "REPO_PATH/.venv/lib/python3.10/site-packages/django/utils/module_loading.py", line 30, in import_string
return cached_import(module_path, class_name)
File "REPO_PATH/.venv/lib/python3.10/site-packages/django/utils/module_loading.py", line 15, in cached_import
import_module(module_path)
File "/opt/homebrew/Cellar/[email protected]/3.10.4/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "REPO_PATH/app/api/pagination.py", line 10, in <module>
from ticket.models import Ticket, TicketStatus, TicketType
File "REPO_PATH/app/ticket/models.py", line 106, in <module>
class Ticket(RulesModelMixin, BaseModel, metaclass=RulesModelBase):
File "REPO_PATH/.venv/lib/python3.10/site-packages/rules/contrib/models.py", line 36, in __new__
new_class._meta.rules_permissions = perms
AttributeError: type object 'Ticket' has no attribute '_meta'. Did you mean: 'Meta'?
它似乎与以后的自定义分页有关,但我不认为这是问题的原因,就像以前起作用一样。甚至在
Adding django-rules
to my Django project I am encountering the following issue: I want to add default permissions to my abstract base class and overwrite them, if needed. Below an example of a base class and the inheriting class:
class BaseModel(RulesModelBaseMixin):
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
}
class Ticket(RulesModelMixin, BaseModel, metaclass=RulesModelBase):
name = models.CharField(max_length=512, null=True, blank=True)
After adding this abstract base class, there is this seemingly unrelated error message:
Traceback (most recent call last):
File "REPO_PATH/.venv/lib/python3.10/site-packages/django/utils/module_loading.py", line 30, in import_string
return cached_import(module_path, class_name)
File "REPO_PATH/.venv/lib/python3.10/site-packages/django/utils/module_loading.py", line 15, in cached_import
import_module(module_path)
File "/opt/homebrew/Cellar/[email protected]/3.10.4/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "REPO_PATH/app/api/pagination.py", line 10, in <module>
from ticket.models import Ticket, TicketStatus, TicketType
File "REPO_PATH/app/ticket/models.py", line 106, in <module>
class Ticket(RulesModelMixin, BaseModel, metaclass=RulesModelBase):
File "REPO_PATH/.venv/lib/python3.10/site-packages/rules/contrib/models.py", line 36, in __new__
new_class._meta.rules_permissions = perms
AttributeError: type object 'Ticket' has no attribute '_meta'. Did you mean: 'Meta'?
It seems to have something to do with the custom pagination later on, but I don't think that this is the cause of the problem, as this worked before. The base class case is even mentioned in the docs, but it doesn't work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
basemodel
不应子类rulesmodelbasemixin
,该用作metaclass
。basemodel
不需要metaclass = rulesmodelbasemixin
,因为ticket
hasmetaClass = pruremodelbase
和prure modelbase
子类RulesModelBasemixin
。basemodel
应该子类模型
,因为它定义了要继承的模型字段。模型
还提供了您可能期望的许多功能。Ticket
需要为具有Metaclass = ModelBase
(例如model
)的类子类次级类在问题中显示)。由于票证
子类basemodel
,我们将更改为子类model
,它无需明确的子类Model> Model
。django-rules
不支持Abstract ModelMeta
中的定义rules_permissions
。您可以实现preprocess_rules_permissions
类方法,以在子类上动态定义该方法。您还需要将baseModel
放在pruremodelmixin
ticket 中以覆盖该类方法。您可以通过制作
basemodel
子类rulesmodel
:BaseModel
should not subclassRulesModelBaseMixin
, which is used as ametaclass
.BaseModel
doesn't needmetaclass=RulesModelBaseMixin
though, sinceTicket
hasmetaclass=RulesModelBase
, andRulesModelBase
subclassesRulesModelBaseMixin
.BaseModel
should subclassModel
since it defines model fields meant to be inherited.Model
also provides a lot of functionality that you might expect.Ticket
needs to subclass a class that hasmetaclass=ModelBase
(e.g.Model
) to get_meta
set (the error shown in the question). SinceTicket
subclassesBaseModel
, which we will change to subclassModel
, it does not need to explicitly subclassModel
again.django-rules
does not support definingrules_permissions
in abstract modelMeta
. You can implementpreprocess_rules_permissions
class method to dynamically define that on subclasses. You also need to putBaseModel
beforeRulesModelMixin
inTicket
to override that class method.You can simplify all that by making
BaseModel
subclassRulesModel
: