我想更新用户的某些属性(比如first_name和last_name) 我的json对象通过PUT请求看起来像这样
{
"user" : {
"first_name": "Jack",
"last_name": "shnider",
"password":"admin123"
"email" : "foo@google.com"
},
"employee_zip" : 12345
}
这就是我的观点(我想将现有字段更新为这些新字段)。
这些是序列化程序
class Serializer_UpdateUser(ModelSerializer):
class Meta:
model = User
fields = ('first_name','last_name','password')
class Serializer_UpdateEmployer(ModelSerializer):
user = Serializer_UpdateUser()
class Meta:
model = modelEmployer
fields = [
'user',
'employer_zip',
]
这是观点:
class UpdateProfile_RetrieveUpdateAPIView(RetrieveUpdateAPIView):
queryset = modelEmployer.objects.all()
serializer_class = Serializer_UpdateEmployer
lookup_field = 'user__email'
permission_classes = [permissions.AllowAny]
def update(self, request, *args, **kwargs):
instance = self.get_object() #------>I have the object that I would like to update
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True) #--->Success
现在我想获得一个经过验证的字段(json只包含已更新的字段)。我知道我是否做过这样的事情
serializer.save
我会找回一个modelEmployer,但我会收回此错误
AssertionError at /api/employer/update_profile/employerA@gmail.com/ The `.update()` method does not support writable nested fields by default. Write an explicit `.update()` method for serializer `Employer.api.serializers.Serializer_ListEmployer`, or set `read_only=True` on nested serializer fields. Request Method:
我有两个问题
1 - 为什么保存失败?
2 - 如何从上面的序列化器中获取经过验证的数据?
答案 0 :(得分:1)
保存失败,因为默认情况下django-rest-framework
不处理嵌套序列化程序。
默认情况下,嵌套序列化程序是
只读。如果要支持嵌套的写操作
你需要创建create()和/或update()的序列化器字段
方法以明确指定子关系如何
应该保存。 您必须覆盖序列化程序中的 另一种解决方案是使用drf-writable-nested。它会自动使嵌套的序列化程序可更新。
update
方法以允许该行为:class Serializer_UpdateEmployer(ModelSerializer):
user = Serializer_UpdateUser()
class Meta:
model = modelEmployer
fields = [
'user',
'employer_zip',
]
def update(self, instance, validated_data):
user_data = validated_data.pop('user', {})
user_serializer = Serializer_UpdateUser(instance.user, data=user_data)
user_serializer.save()
return instance
from drf_writable_nested import WritableNestedModelSerializer
class Serializer_UpdateEmployer(WritableNestedModelSerializer):
user = Serializer_UpdateUser()
class Meta:
model = modelEmployer
fields = [
'user',
'employer_zip',
]
答案 1 :(得分:1)
我认为drf-writable-nested可以帮助您更新嵌套数据。
在你的情况下:
from django.contrib.auth import password_validation
class Serializer_UpdateUser(ModelSerializer):
def update(self, instance, validated_data):
password = validated_data.pop('password', None)
super(Serializer_UpdateUser, self).update(instance, validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
def validate_password(self, value):
password_validation.validate_password(value)
return value
class Meta:
model = User
fields = ('first_name','last_name','password')
class Serializer_UpdateEmployer(WritableNestedModelSerializer):
user = Serializer_UpdateUser()
class Meta:
model = modelEmployer
fields = [
'user',
'employer_zip',
]
请注意,您需要特殊处理password
字段。