Django Rest Framework和字段级权限

时间:2015-09-10 12:56:49

标签: django rest django-rest-framework

我想构建一个具有字段级权限的API。我从数据库表中获取这些权限,但是在REST框架中哪里可以检查用户是否可以对对象的字段执行CRUD操作?

database --- model ---- ModelSerializer ---- ModelViewSet --- browser

在ModelSerializer中?在这里我可以在他们到达视图集之前删除字段但是我默认无法访问request.user,所以我必须实现它,这可以完成,但不能与我拥有的其他第三方库一起使用(django的静止-招摇)

还是在ModelViewset中?我可以覆盖列表,创建,更新和销毁方法以删除用户无权访问的字段。但是这对我的元数据实现不起作用,因为它直接从序列化器获取元数据。

或许两者兼而有之?例如:当通过序列化程序获取模型时,删除不允许在序列化程序中读取,并在之前删除viewset 中的not-allowed-writes >他们被传回序列化器?

2 个答案:

答案 0 :(得分:0)

如果您使用的是GenericView,默认情况下DRF会将请求对象放入序列化程序对象的上下文中。您可以通过

访问用户信息

self.context['request'].user

答案 1 :(得分:0)

from utils.mixins import MultiSerializerViewSetMixin


class UserViewSet(MultiSerializerViewSetMixin, ModelViewSet):
    serializer_class = UserSerializer
    serializer_action_classes = {
        'update': UserDetailSerializer,
    }
    permission_classes = (UserPermission,)
    queryset = User.objects.all()

MultiSerializerViewSetMixin的源代码: https://gist.github.com/gonz/10044002

我用两个串行器解决了我的问题:

from django.contrib.auth.models import User
from rest_framework import serializers


class UserSerializerMixin(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    is_superuser = serializers.BooleanField(read_only=True)
    first_name = serializers.CharField(max_length=30, required=False, allow_blank=True)
    last_name = serializers.CharField(max_length=30, required=False, allow_blank=True)
    email = serializers.EmailField(required=False, allow_blank=True)

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

    def update(self, instance, validated_data):
        instance.first_name = validated_data.get('first_name', instance.first_name)
        instance.last_name = validated_data.get('last_name', instance.last_name)
        instance.email = validated_data.get('email', instance.email)
        password = validated_data.get('password', '')
        if password:
            instance.set_password(password)
            instance.save()
        return instance

    class Meta:
        model = User


class UserSerializer(UserSerializerMixin):
    username = serializers.CharField(max_length=30)
    password = serializers.CharField(
        max_length=128, write_only=True,
        style={'input_type': 'password'})


class UserDetailSerializer(UserSerializerMixin):
    username = serializers.CharField(read_only=True)
    password = serializers.CharField(
        max_length=128, write_only=True,
        style={'input_type': 'password'},
        required=False, allow_blank=True
    )

你可以使用MultiSerializerViewSetMixin,我去年发现它并使用mixins创建两个不同但相似的序列化器。