在数据迁移中创建自定义权限

Creating custom permission in data migration

我试图在迁移中创建自定义权限,但是在 运行 迁移之后,权限并未在权限 table 中创建。有人可以指出错误是什么吗? 此外,我不确定我应该使用什么作为 ContentType 的相关模型,因为该权限用于限制可以查看显示网站上用户摘要的页面的用户。 非常感谢任何帮助,谢谢。

def add_view_aggregated_data_permissions(apps, schema_editor):
    ContentType = apps.get_model('django', 'ContentType')
    Permission = apps.get_model('auth', 'Permission')
    content_type = ContentType.objects.get(app_label='auth', model='user')
    permission = Permission.objects.create(codename='can_view_data',
                                           name='Can view data',
                                           content_type=content_type)

我建议您使用 Django documentation 中描述的标准方式来使用自定义权限。您将完全避免许多问题。

To create custom permissions for a given model object, use the permissions model Meta attribute.

此示例模型创建自定义权限:

class MyModel(models.Model):
    ...
    class Meta:
        permissions = (
            ('view_data', "Can see available data"),
        )

The only thing this does is create those extra permissions when you run manage.py migrate. Your code is in charge of checking the value of these permissions when a user is trying to access the functionality provided by the application...

然后你可以在你的视图中使用 permission_required 装饰器来检查特定权限:

from django.contrib.auth.decorators import permission_required

@permission_required('myapp.view_data')
def my_view(request):
    ...

从 django 1.8 开始,built-in 迁移非常轻松。

  1. 您需要做的就是将您想要的权限添加到相关的 型号
  2. 运行 迁移

    ./manage.py makemigrations

  3. 运行 上述步骤中创建的迁移

    ./manage.py 迁移

我想为所有应用程序模型创建自定义权限(读取)。我做了这两个步骤:

  1. 从 DjangoModelPermissions 创建扩展权限:

    class DjangoModelPermissionsExtended(DjangoModelPermissions):
        """
        """
        perms_map = {
            'GET': ['%(app_label)s.read_%(model_name)s'],
            'OPTIONS': [],
            'HEAD': [],
            'POST': ['%(app_label)s.add_%(model_name)s'],
            'PUT': ['%(app_label)s.change_%(model_name)s'],
            'PATCH': ['%(app_label)s.change_%(model_name)s'],
            'DELETE': ['%(app_label)s.delete_%(model_name)s'],
        }
    
  2. 放在每个视图中我要读权限:

    class ExampleViewSet(viewsets.ModelViewSet):
        permission_classes = (
            DjangoModelPermissionsExtended,
        )
    
  3. 创建 django command customread.py:

    from django.core.management.base import BaseCommand, CommandError
    from project.app import models as app_models
    from django.db import models
    from django.contrib.auth.models import Permission
    from django.contrib.contenttypes.models import ContentType
    import inspect
    
    class Command(BaseCommand):
    help = 'Create the read permission to app models'
    
    def handle(self, *args, **options):
        for name, obj in inspect.getmembers(app_models):
            if inspect.isclass(obj) and issubclass(obj, models.Model):
                try:
                    self.add_canread(obj)
                    self.stdout.write(self.style.SUCCESS(
                        'created permission for %s' % obj
                    ))
                except Exception as e:
                    self.stdout.write(self.style.ERROR(
                        'Permission already exists for %s' % obj
                    ))
    
    def add_canread(self, object_class):
        """This a function that can be executed in order to create
        new permissions (read view) to a class in DB.
    
        """
        if inspect.isclass(object_class):
            content_type = ContentType.objects.get_for_model(object_class)
            permission = Permission.objects.create(
                codename='read_{}'.format(object_class._meta.model_name),
                name='Can view {}'.format(object_class.__name__),
                content_type=content_type,
            )
        else:
            msg = "The object is not a class"
            print(msg)
    
  4. 迁移后执行:

    python manage.py customread