как можно использовать пользовательские разрешения djangorestframework - PullRequest
0 голосов
/ 24 мая 2019

У меня есть проект, и теперь я хочу добавить мою новую конечную точку в этот проект, которая отвечает json. этот json очень прост и не нуждается в каком-либо сериализаторе или queryset.но я не знаю, как я могу использовать permision_class в этой конечной точке? Второй вопрос, что такое "obj" в def has_object_permission(self, request, view, obj): есть? откуда взято? tnx.

view.py:


class TeacherPostStatistic(generics.RetrieveAPIView):
    permission_classes = (ClassCoTeacherPermission, ClassOwnerPermission)

    def get_klass(self):
        class_id = self.kwargs['class_id']
        return Class.objects.get(id=class_id)

    def get(self, request, *arg, **kwargs):
        klass = self.get_klass()
        response = Post.post_count_last7days(klass)
        return JsonResponse(response, safe=False)

model.py:

class Post(models.Model):
    # some field 

    @classmethod
    def post_count_last7days(cls, klass):
        post_per_day_chart = {}
        for past_day in range(0, 7):
            count_post_in_past_day = cls.objects.filter(klass__exact=klass, create_date__date=date.today()-timedelta(days=past_day)).count()
            post_per_day_chart[past_day] = count_post_in_past_day
        return post_per_day_chart

permission.py:

# TODO: using raise inside permission class should be revised
class ClassCoTeacherPermission(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        print("in coteachers: ",obj)
        return self.has_perm(user=request.user, klass=obj)

    @classmethod
    def has_perm(cls, user, klass):
        co_teacher = ClassCoTeacherMembership.objects.filter(klass=klass, co_teacher=user)
        if not co_teacher.exists():
            raise exc.UserIsNotCoTeacherOfTheClass
        return True

class ClassOwnerPermission(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `owner` attribute.
    """

    @classmethod
    def has_perm(cls, user, klass):
        return klass.owner == user

    def has_object_permission(self, request, view, obj):
        print("im in ",obj)
        return self.has_perm(request.user, obj)

если понадобятся какие-либо изменения для решения этой проблемы, дайте мне знать, плз. например, изменить generics.RetrieveAPIVie на APIView или ViewSet или т. д.

1 Ответ

3 голосов
/ 24 мая 2019

Вам необходимо обновить has_perm метод в обоих классах разрешений:

class ClassCoTeacherPermission(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        print("in coteachers: ",obj)
        return self.has_perm(user=request.user, klass=obj)


    def has_perm(self, user, klass):
        co_teacher = ClassCoTeacherMembership.objects.filter(klass=klass, co_teacher=user)
        if not co_teacher.exists():
            raise exc.UserIsNotCoTeacherOfTheClass
        return True

class ClassOwnerPermission(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `owner` attribute.
    """

    def has_perm(self, user, klass):
        return klass.owner == user

    def has_object_permission(self, request, view, obj):
        print("im in ",obj)
        return self.has_perm(request.user, obj)

Поскольку, когда вы вызываете их, вы используете self, это означает, что вы вызываете их через объект, ноВы объявили их как classmethod, который должен выдать ошибку.Более подробную информацию можно найти здесь о различиях между методом класса и методом объекта.

...