Django Rest Framework:最佳实践?

10

我在想,当涉及到Django Rest Framework时,最佳实践是什么。我一直通过使用不同的序列化程序(针对员工、帐户所有者和其他任何人)和HTTP方法来限制更改帐户某些属性的访问,但我觉得这太不符合Python风格了。

这是否是实现将对象的不同字段的“权限”分离出来的最佳方法?还是有更好、更符合Python风格的方法来完成我目前所做的事情?

我接受以下代码的任何批评,因为我觉得我有些地方偷懒了。

非常感谢。

from rest_framework import serializers, viewsets
from rest_framework.permissions import SAFE_METHODS
from accounts.models import User
from cpapi.permissions import *


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'url', 'username', 'password')
        write_only_fields = ('password',)

    def restore_object(self, attrs, instance=None):
        user = super(UserSerializer, self).restore_object(attrs, instance)
        if 'password' in attrs.keys():
            user.set_password(attrs['password'])
        return user

class UserDetailsSerializer(UserSerializer):
    class Meta(UserSerializer.Meta):
        fields = ('id', 'url', 'username', 'password', 'email')

class UserListSerializer(UserSerializer):
    class Meta(UserSerializer.Meta):
        fields = ('id', 'url', 'username')

class UserWithoutNameSerializer(UserSerializer):
    class Meta(UserSerializer.Meta):
        fields = ('id', 'url', 'password', 'email')


class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    serializer_class = UserSerializer
    model = User

    def get_serializer_class(self): # Modify to allow different information for different access (userlist vs staff)
        serializer_class = self.serializer_class
        if 'List' in self.get_view_name():
            serializer_class = UserListSerializer
        elif self.request.method in ['PUT', 'PATCH']:
            serializer_class = UserWithoutNameSerializer
        elif self.get_object() == self.request.user or self.request.user.is_staff:
            serializer_class = UserDetailsSerializer
        return serializer_class

    def get_permissions(self):
        if self.request.method in SAFE_METHODS or self.request.method == 'POST':
            return [AllowAny()]
        elif self.request.method == 'DELETE':
            return [IsAdminUser()]
        else:
            return [IsStaffOrTargetUser()]
1个回答

2
如果我理解正确,您想要的是每个字段的权限,而不是Django或Django-REST-Framework直接支持它们。您可以安装类似于Django Fine-Grained Permissions的包,但是由于没有办法将这些权限传达给REST API视图,您会陷入同样的困境。
我建议您坚持自己的解决方案,或者将序列化器选择逻辑放在一个具有所有字段的序列化器中,并将角色传递给构造函数,让序列化器根据角色构建字段列表,但要使其工作,您需要编写自己的Serializer子类。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接