Bra*_*don 58 django rest django-rest-framework
我正在尝试通过Django Rest Framework API调用使我的用户模型RESTful,以便我可以创建用户以及更新他们的配置文件.
但是,当我与用户进行特定的验证过程时,我不希望用户在创建帐户后能够更新用户名.我试图使用read_only_fields,但这似乎在POST操作中禁用了该字段,因此在创建用户对象时我无法指定用户名.
我该如何实现呢?现在存在的API的相关代码如下.
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'password', 'email')
write_only_fields = ('password',)
def restore_object(self, attrs, instance=None):
user = super(UserSerializer, self).restore_object(attrs, instance)
user.set_password(attrs['password'])
return user
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
serializer_class = UserSerializer
model = User
def get_permissions(self):
if self.request.method == 'DELETE':
return [IsAdminUser()]
elif self.request.method == 'POST':
return [AllowAny()]
else:
return [IsStaffOrTargetUser()]
Run Code Online (Sandbox Code Playgroud)
谢谢!
And*_*dov 53
看来你需要为POST和PUT方法使用不同的序列化器.在PUT方法的序列化器中,您只能使用用户名字段(或将用户名字段设置为只读).
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
serializer_class = UserSerializer
model = User
def get_serializer_class(self):
serializer_class = self.serializer_class
if self.request.method == 'PUT':
serializer_class = SerializerWithoutUsernameField
return serializer_class
def get_permissions(self):
if self.request.method == 'DELETE':
return [IsAdminUser()]
elif self.request.method == 'POST':
return [AllowAny()]
else:
return [IsStaffOrTargetUser()]
Run Code Online (Sandbox Code Playgroud)
检查这个问题django-rest-framework:在相同的URL中使用不同的泛型视图的独立GET和PUT
小智 23
另一种选择(仅限DRF3)
class MySerializer(serializers.ModelSerializer):
...
def get_extra_kwargs(self):
extra_kwargs = super(MySerializer, self).get_extra_kwargs()
action = self.context['view'].action
if action in ['create']:
kwargs = extra_kwargs.get('ro_oncreate_field', {})
kwargs['read_only'] = True
extra_kwargs['ro_oncreate_field'] = kwargs
elif action in ['update', 'partial_update']:
kwargs = extra_kwargs.get('ro_onupdate_field', {})
kwargs['read_only'] = True
extra_kwargs['ro_onupdate_field'] = kwargs
return extra_kwargs
Run Code Online (Sandbox Code Playgroud)
另一种方法是添加验证方法,但如果实例已存在且值已更改,则抛出验证错误:
def validate_foo(self, value):
if self.instance and value != self.instance.foo:
raise serializers.ValidationError("foo is immutable once set.")
return value
Run Code Online (Sandbox Code Playgroud)
就我而言,我希望永远不会更新外键:
def validate_foo_id(self, value):
if self.instance and value.id != self.instance.foo_id:
raise serializers.ValidationError("foo_id is immutable once set.")
return value
Run Code Online (Sandbox Code Playgroud)
另请参阅:django rest framework 3.1 中的级别字段验证 - 访问旧值
我的方法是perform_update在使用泛型视图类时修改方法。我在执行更新时删除该字段。
class UpdateView(generics.UpdateAPIView):
...
def perform_update(self, serializer):
#remove some field
rem_field = serializer.validated_data.pop('some_field', None)
serializer.save()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17228 次 |
| 最近记录: |