在django rest框架中实现角色

时间:2016-12-21 22:33:07

标签: python django django-rest-framework

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

super_user - 创建/管理管理员

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

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

其他我希望每种类型的用户都有电话号码字段

tried

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)

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

2 个答案:

答案 0 :(得分:5)

可能的解决方案之一是:

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

说明:

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

  2. 了解有关Django用户组的更多信息。请参阅此处:Django Permissions Docs #1此处:Django Groups Docs #2此处也有用链接:StackOverflow question

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

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

    2. 现在一切都准备好用户角色限制访问了。您可以使用权限类轻松限制对DRF View的访问。 (详见DRF Permission Docs

    3. 让我们自己定义。

      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
      

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

      希望有所帮助。

答案 1 :(得分:1)

因此,在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(我是作者)或监护人之类的第三方库。