我有一个功能 make_fields_permissions
我需要在模型类中使用它来解析字段并为每个字段设置权限,例如 [('can_view_first_name_field','can view first name'),...]
Person
类和内部自我
def __init__(self,*args, **kwargs):
self.Meta.permissions = make_fields_permissions(self.model)
super().__init__(*args, **kwargs)
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def __init__(self, *args, **kwargs):
# kwargs['user']['permissions'] = make_fields_permissions(Profile)
# x = self['age']
super().__init__(*args, **kwargs)
class Meta:
permissions = make_fields_permissions(Person) #< I can't use the same model inside meta
最佳答案
您的目标如下:
Note: See What is the XY problem?
让我们先讨论目标 Y 以及为什么它太复杂,而且有些不可行。当想要自定义类的创建方式时,可以使用 metaclasses ,乍一看,这似乎是满足您需求的完美解决方案(事实上,如果您确实创建了一个正确的解决方案,那就是)。但这里的问题是
Model
已经有一个元类是 ModelBase
它已经在做很多事情,而且有点复杂。如果我们想要一个自定义元类,我们需要从它继承并非常仔细地围绕它的实现来做我们想做的事情。此外,制作它并不是故事的结局,因为那样我们就需要维护它,因为它很容易被 Django 更新破坏。因此 目标 Y 不可行。转到实际 目标 X 要做到这一点,可以 Programmatically create permissions [Django docs] .执行此操作的一个好地方是在应用程序配置中
ready
方法。对于使用 startapp
创建的所有应用程序有一个 apps.py
具有从 AppConfig
继承的 appconfig 的文件, 当模型加载时它的 ready
方法被调用。因此,此方法用于执行各种任务,例如附加信号、各种设置,例如任务等。修改应用程序的 appconfig 以编程方式创建权限,如下所示:from django.apps import AppConfig
class YourAppConfig(AppConfig):
default_auto_field = 'django.db.models.AutoField' # Don't modify, keep it as it is in your code
name = 'your_app' # Don't modify, keep it as it is in your code
def ready(self):
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from path.to import make_fields_permissions
from .models import Person
# import models here, not outside as models may not be loaded yet
content_type = ContentType.objects.get_for_model(Person)
for codename, name in make_fields_permissions(Person):
Permission.objects.get_or_create(
codename=codename, # 'can_view_first_name_field'
name=name, # 'can view first name'
content_type=content_type,
)
关于python - Django:如何在其自身内部调用相同的模型类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67858169/