繁体   English   中英

在 django rest 框架中实现角色

[英]Implement roles in django rest framework

我正在构建一个应具有以下类型用户的 API

super_user - 创建/管理管理员

admin - 管理事件(模型)和事件参与者

participants - 参加活动,受管理员邀请参加活动

另外我想让每种类型的用户都有电话号码字段

试过了

class SuperUser(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone_number = models.CharField(max_length=20)

class Admin(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone_number = models.CharField(max_length=20)


class Participant(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone_number = models.CharField(max_length=20)

但是直觉告诉我这是一种错误的处理方式。 有人可以帮忙吗。

一种可能的解决方案是:

    1. 只有一个带有角色字段的用户模型,它定义了用户角色是什么。
    1. 创建一个用户组并添加每个组所需的权限。
    1. 将用户添加到用户组
    1. 使用 Django REST Framework(后来的 DRF)权限类限制访问。

解释:

  1. 仅使用一个用户模型是一种更简单灵活的解决方案。 您可以查询所有用户,或按功能(如用户角色)过滤。 标准 Django 身份验证系统需要一个 UserModel。

  2. 阅读有关 Django 用户组的更多信息。 请参阅“ Django 权限文档#1 ”和“ Django 组文档#2 ”。 同样有用的是“ 用户组和权限”。

您需要为每个用户角色创建一个组,并为每个组添加所需的权限。 (Django 有一个默认的模型权限,自动创建,查看给定链接上的文档)或在模型定义中手动创建所需的权限。

  1. 手动或使用脚本,通过在创建用户时定义他的角色或通过 Django 管理界面手动将用户添加到所需的组。

  2. 现在一切都应该准备就绪,可以通过用户角色进行有限访问。 您可以使用权限类轻松限制对 DRF 视图的访问。 在“ DRF 权限文档”中查看更多信息。

让我们定义我们自己的:

from rest_framework.permissions import DjangoModelPermissions
# Using DjangoModelPermissions we can limit access by checking user permissions.

# Rights need only for CreateUpdateDelete actions.
class CUDModelPermissions(DjangoModelPermissions):
  perms_map = {
      'GET': [],
      'OPTIONS': [],
      'HEAD': ['%(app_label)s.read_%(model_name)s'],
      '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'],
  }

# Or you can inherit from BasePermission class and define your own rule for access
from rest_framework.permissions import BasePermission

class AdminsPermissions(BasePermission):
    allowed_user_roles = (User.SUPERVISOR, User.ADMINISTRATOR)

    def has_permission(self, request, view):
        is_allowed_user = request.user.role in self.allowed_user_roles
        return is_allowed_user

# ----
# on views.py

from rest_framework import generics
from .mypermissions import CUDModelPermissions, AdminsPermissions

class MyViewWithPermissions(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = [CUDModelPermissions, ]
    queryset = SomeModel.objects.all()
    serializer_class = MyModelSerializer

您可以添加额外的权限类来组合访问限制。

所以在 Django 中,任何用户都有一个标志is_superuser对应于你的“超级用户”。 所以只需使用它 - 例如User.objects.create(is_superuser=True)

对于其余部分,您可以简单地使用普通用户模型的字段来区分普通用户的子角色。

class User(AbstractBaseUser):
    can_participate_event = models.Boolean(default=False)
    can_create_event = models.Boolean(default=False)

或者

class User(AbstractBaseUser):
    permissions = models.CharField(default='')  # and populate with e.g. 'create_event,participate_event'

您仍然可能需要检查视图中的所有这些字段。 你添加到你的应用程序中越多,它就会变得越多,所以我建议使用像rest-framework-roles (我是作者)或监护人这样的 3rd 方库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM