如何使用自定义权限djangorestframework

时间:2019-05-24 10:42:01

标签: django permissions django-rest-framework

我有一个项目,现在我想向该项目添加一个新的终结点,以响应json。这个json非常简单,不需要任何序列化程序或queryset。但是我不知道如何在此端点中使用permision_class?第二个问题是docker login localhost:443中的“ obj”是什么?哪里来的?tnx。

view.py:

docker run -d   --restart=always   --name registry   -v `pwd`/auth:/auth   -v `pwd`/certs:/certs   -v `pwd`/certs:/certs   -e REGISTRY_AUTH=htpasswd   -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm"   -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd   -e REGISTRY_HTTP_ADDR=0.0.0.0:443   -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt   -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key   -p 443:443   registry:2

model.py:

def has_object_permission(self, request, view, obj):

permission.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)

如果需要任何更改来解决此问题,请通知我。例如将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 更改为# 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等。

1 个答案:

答案 0 :(得分:3)

您需要同时更新两个权限类中的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,这意味着您通过对象调用它们,但是将它们声明为类方法,这会引发错误。有关类方法和对象方法之间的区别,请参见found here