我想构建一个具有字段级权限的API。我从数据库表中获取这些权限,但是在REST框架中哪里可以检查用户是否可以对对象的字段执行CRUD操作?
database --- model ---- ModelSerializer ---- ModelViewSet --- browser
在ModelSerializer中?在这里我可以在他们到达视图集之前删除字段但是我默认无法访问request.user,所以我必须实现它,这可以完成,但不能与我拥有的其他第三方库一起使用(django的静止-招摇)
还是在ModelViewset中?我可以覆盖列表,创建,更新和销毁方法以删除用户无权访问的字段。但是这对我的元数据实现不起作用,因为它直接从序列化器获取元数据。
或许两者兼而有之?例如:当通过序列化程序获取模型时,删除不允许在序列化程序中读取,并在之前删除viewset 中的not-allowed-writes >他们被传回到序列化器?
答案 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创建两个不同但相似的序列化器。