在基于序列化器的api上为不同类型的请求设置不同的权限(使用路由器)?

时间:2018-07-20 02:19:06

标签: django django-rest-framework

我正在使用DRF并使用单个URL来处理所有用户操作,例如LIST,GET,POST等。

我曾经使用过路由器,但无法找到调整诸如...之类的权限的方法。

  • 甚至匿名用户也可以创建用户。
  • 只有注册用户(或管理员)可以删除自己的帖子。 依此类推。

urls.py

from django.urls import path, include, re_path
from .api import UserAPI
from rest_framework.routers import DefaultRouter


urlpatterns = [

    # path('register/<int:pk>', UserAPI.as_view(), name='user_create'),


]

router = DefaultRouter()
router.register(r'user', UserAPI)
urlpatterns = [

              ] + router.urls

Serializers.py

from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.forms import ValidationError


User = get_user_model()


class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = '__all__'
        write_only_fields = ('password',)
        read_only_fields = ('id',)
        extra_kwargs = {'last_name': {'required': True}}

    password = serializers.CharField(write_only=True)

    def create(self, validated_data):

        user = User.objects.create(email=validated_data['email'],
                                   first_name=validated_data['first_name'],
                                   last_name=validated_data['last_name'],
                                   )

        user.set_password(validated_data['password'])
        user.save()
        return user

api.py

from rest_framework.viewsets import ModelViewSet
from django.contrib.auth import get_user_model  # used custom user model
from rest_framework import mixins
from .serializers import UserSerializer

User = get_user_model()


class UserAPI(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

2 个答案:

答案 0 :(得分:1)

创建一个自定义权限类并定义所需的所有内容。 例子

from rest_framework.compat import is_authenticated
from rest_framework import permissions

class MyCustomPermissionClass(permissions.BasePermission):
    def is_authenticated(self, request):
        return request.user and is_authenticated(request.user)

    def has_permission(self, request, view):
        if view.action == 'create':  # create new user by anyone
            return True
        if is_authenticated(request) and view.action == 'destroy' and request.user == post_created_by_user:
            return True
        # add all other conditions you want to implement
        return False  # default case


并将权限类别添加到您的视图中

from .permissions import MyCustomPermissionClass

class UserAPI(ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer permission_classes = (MyCustomPermissionClass,)


您应该记住一件事,除非权限类返回布尔值True,否则您将不会获得允许访问相应视图的权限

阅读有关DRF- Custom Permissions的更多信息

于31-07-2018更新
rest_framework.compat.is_authenticated被描述。 request.user.is_authenticated 将执行相同的操作

from rest_framework import permissions


class MyCustomPermissionClass(permissions.BasePermission):
    def is_authenticated(self, request):
        return request.user and request.user.is_authenticated

    def has_permission(self, request, view):
        if view.action == 'create':  # create new user by anyone
            return True
        if self.is_authenticated(request) and view.action == 'destroy' and request.user == post_created_by_user:
            return True
        # add all other conditions you want to implement
        return False  # default case

答案 1 :(得分:0)

permissions.py

from rest_framework.permissions import BasePermission

class UserPermissions(BasePermission):
    def has_permission(self, request, view):
        # request.user.is_authenticated to make sure user is authed
        # view.action == 'create' will allow Even anonymous users can create users.
        return request.user.is_authenticated or view.action == 'create'

    def has_object_permission(self, request, view, obj):
        # obj == request.user make sure the changeing(update/read/delete) user is itself and only itself.
        # if you want authed user can read and only myself can update\delete ,change it to obj == request.user or view.action == 'retrieve'
        return obj == request.user

views.py

class UserAPI(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (UserPermissions,)