繁体   English   中英

Django per-model授权权限

[英]Django per-model authorization permissions

我在 Django 中遇到授权权限问题(对 Django 有点陌生)。 我有一个老师、学生和经理模型。 当老师向我的 API 发送请求时,他们应该获得与学生不同的权限(即,学生将看到他自己的所有考试成绩,而老师可以看到自己班级的所有学生,经理可以看到所有内容) .

我的问题如下:

  1. 如何让我的所有模型都成为有效的系统用户? 我试过添加
models.OneToOneField(User, on_delete=models.CASCADE)

但这需要创建一个用户,然后将其分配给老师。 我想要的是让实际的老师“实例”成为被使用的用户。

  1. 如何检查我的用户是哪种“类型”? 他们是老师、学生还是经理? 每次用户发送请求时,我是否需要对所有 3 个表进行 go,并找出它们属于哪个表? 听起来不对。 我考虑过创建一个带有“类型”列的全局“用户”表,但是我无法将特定列添加到我的模型中(即学生应该有一个平均成绩而老师不应该)。

将不胜感激任何指向正确方向的指示。

当您需要多种用户类型时,例如,在您的情况下需要多个角色,如学生、教师、经理等……那么您需要一个不同的角色来对所有人进行分类。 要拥有这些角色,您需要在models.py中为您的User model 扩展AbstractUser (对于简单情况)。您还可以在模型中指定权限。 使用permissions字段在模型的class Meta上附加权限。 您可以根据需要指定任意数量的权限,但它必须位于如下元组中:

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.db.models.fields.related import ForeignKey
from django.utils.translation import gettext as _


class Role(models.Model):
  STUDENT = 1
  TEACHER = 2
  MANAGER = 3
  ROLE_CHOICES = (
      (STUDENT, 'student'),
      (TEACHER, 'teacher'),
      (MANAGER, 'manager'),
  )

  id = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, primary_key=True)

  def __str__(self):
      return self.get_id_display()

class User(AbstractUser):
    roles = models.ManyToManyField(Role)
    username = models.CharField(max_length = 50, blank = True, null = True, unique = True)
    email = models.EmailField(_('email address'), unique = True)
    native_name = models.CharField(max_length = 5)
    phone_no = models.CharField(max_length = 10)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
    def __str__(self):
        return "{}".format(self.email)

class Student(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='students')
    sample_field_name = models.CharField(max_length = 50, blank = True, null = True)

    class Meta:
        permissions = (("sample_permission", "can change sth of sth"),)


class Teacher(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='teachers')
    sample_field_name = models.CharField(max_length = 50, blank = True, null = True)

    class Meta:
        permissions = (("sample_permission", "can change sth in sth"),)

class Manager(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='managers')
    sample_field_name = models.CharField(max_length = 50, blank = True, null = True)

    class Meta:
        permissions = (("sample_permission", "can change sth in sth"),)

之后,您应该拥有您的视图权限并添加权限以将 function 限制为仅具有该特定权限的用户可以通过使用 Django 内置装饰器来完成,基于函数的视图需要permission_required ::

from django.contrib.auth.decorators import permission_required

@permission_required('students.sample_permission')
def student_sample_view(request):
    """Raise permission denied exception or redirect user"""

如果你使用基于类的视图,你只需要使用一个 mixin, PermissionRequiredMixin

from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic import ListView

class SampleListView(PermissionRequiredMixin, ListView):
    permission_required = 'students.sample_permission'
    # Or multiple permissions
    permission_required = ('students.sample_permission', 'teachers.other_sample_permission')

这是您在 Django 项目中管理多个角色的一种方式,您还可以在以下博客和参考资料中找到更多方式:

暂无
暂无

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

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