在django rest框架中实现角色

Emm*_*ali 3 python django 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)
Run Code Online (Sandbox Code Playgroud)

但是直觉告诉我这是一个错误的方法来处理这个问题.有人可以请帮助.

Ant*_*kiy 6

可能的解决方案之一是:

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

说明:

  1. 仅使用一个用户模型就是更加简单灵活的解决方案.您可以查询所有用户,也可以按功能过滤(如用户角色).Standart Django auth系统期望一个UserModel.

  2. 阅读有关Django用户组的更多信息.请参阅:Django权限文档#1在这里:Django Groups Docs#2此处也有用链接:StackOverflow问题

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

  1. Manualy或programable通过定义他的角色将用户添加到所需的组.(当用户创建或由Django Admin界面手动创建时)

  2. 现在一切都准备好用户角色限制访问了.您可以使用权限类轻松限制对DRF View的访问.(在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
Run Code Online (Sandbox Code Playgroud)

您可以添加其他权限类以组合访问限制.

希望它有所帮助.


Pit*_*kos 5

is_superuser因此,在 Django 中,任何用户都有一个与您的“超级用户”相对应的标志。所以就用那个 - 例如User.objects.create(is_superuser=True)

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

class User(AbstractBaseUser):
    can_participate_event = models.Boolean(default=False)
    can_create_event = models.Boolean(default=False)
Run Code Online (Sandbox Code Playgroud)

或者

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

您仍然可能需要检查您视图中的所有这些字段。您向应用程序添加的内容越多,问题就变得越多,因此我建议使用第三方库,例如rest-framework-roles(我是作者)或监护人。