Пользовательский класс разрешений Django Rest Framework с ManyToManyField - PullRequest
0 голосов
/ 03 октября 2019

Я пытаюсь написать класс разрешений для django rest api view.

это мои модели

from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    name = models.CharField(max_length=50)
    auth_user = models.OneToOneField(User, on_delete=models.CASCADE)

class Group(models.Model):
    admin = models.ManyToManyField(Profile, related_name='g_admin')
    members = models.ManyToManyField(Profile, related_name='g_mess')

Я хочу, чтобы только администратор группы мог выполнять действие на определенных страницах, дляэто я пишу класс разрешений:

class IsGroupAdmin(BasePermission):
    """
    Allows access only to Group Admin.
    """

    def has_permission(self, request, view):
        # return bool() do something here

У меня возникают проблемы с написанием класса разрешений, чтобы проверить, является ли группа администратором или нет. Я сталкиваюсь с проблемой, потому что это поле для многих.

Кто-нибудь может мне помочь написать это?

Ответы [ 2 ]

0 голосов
/ 12 октября 2019

Вы можете получить User от request.user. Я не знаю, как вы можете получить Group из запроса (это может быть в полезной нагрузке запроса, это зависит от вашего дизайна), но давайте предположим, что вы передаете Group в класс разрешений, тогда это будет что-товот так:

class IsGroupAdmin(BasePermission):
    """
    Allows access only to Group Admin.
    """
    def __init__(self, group):
        super().__init__()
        self.group = group

    def has_permission(self, request, view):
        return self.group.profile_set.filter(auth_user=request.user).any()

Примечание: если вы можете получить группу из запроса, вам не нужно передавать group в класс IsGroupAdmin, и это будет намного проще. Но если вы не можете этого сделать и собираетесь использовать только указанный выше класс разрешений, вам понадобится функция partial. поэтому вам нужно импортировать его:

from functools import partial

А затем в представлениях инициировать permission_classes следующим образом:

permission_classes = [partial(IsGroupAdmin, group)]

Однако я предлагаю вам использовать более простой способ, потому чтоЯ думаю, что group должно быть в request. Допустим, group находится в полезной нагрузке запроса, тогда вы должны реализовать IsGroupAdmin как:

class IsGroupAdmin(BasePermission):
    """
    Allows access only to Group Admin.
    """

    def has_permission(self, request, view):
        group = request.data.get('group', '')
        return group.profile_set.filter(auth_user=request.user).any()

И использовать его как обычное разрешение. (не нужно использовать partial функцию)

0 голосов
/ 12 октября 2019

ваша структура данных неверна admin и члены должны быть m2m с user не с Profile .

для разрешения вы должны сделать запрос наподобие Group.objects.filter (admin__auth_user__id = request.id) с возвращением true else.

использование через таблицу уменьшит вашу работу и создаст какой-то флаг, который даетВы полагаете, что запрос пользователя является администратором или нет (в модели пользователя используется сигнал), поэтому каждый раз, когда вам не нужно запускать запрос в базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...