我尝试使用this answer中的方法扩展用户模型。
我的想法是只在每次向api发出关于用户的请求时发送配置文件对象。
我完成了以下工作:
# views.py
class ProfileDetail(APIView):
"""
Retrieve or update a profile instance.
"""
permission_classes = (permissions.IsAuthenticatedOrReadOnly, )
...
def get(self, request, pk, format=None):
...
# Only allow owners to update a profile
def put(self, request, pk, format=None):
profile = self.get_object(pk)
if request.user != profile.user:
raise PermissionDenied
serializer = OwnerProfileSerializer(
profile,
data=request.data,
context={"request": request},
)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
我的序列化器看起来像这样:
#serializers.py
# Serializer for the owner of profile object
class OwnerProfileSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.ReadOnlyField(source='user.id')
first_name = serializers.ReadOnlyField(source='user.first_name')
last_name = serializers.ReadOnlyField(source='user.last_name')
email = serializers.(source='user.email')
class Meta:
model = Profile
fields = (
'url',
'id',
'dob',
'bio',
'town',
'gender',
'image',
'user',
'first_name',
'last_name',
'email',
)
我希望所有者也能够修改user
个对象字段,例如first_name
,last_name
,email
等。
但是我没有在DRF序列化程序文档中找到(例如)ReadWriteField
。
我怎么能做到这一点?如果可能,我希望通过Profile视图/序列化程序而不是用户执行所有修改。
- 编辑 -
作为测试,我将ReadOnlyField
替换为last_name = serializers.CharField(source='user.last_name')
。当我尝试更新它时,DRF给了我这个错误:
.update()
方法不支持可写的点源字段 默认情况下。为序列化器编写明确的.update()
方法profiles.serializers.OwnerProfileSerializer
,或设置read_only=True
在点源序列化器字段上。
所以看起来我可以实现自己的update
方法。但我不确定如何继续。
答案 0 :(得分:1)
我设法通过在序列化程序上扩展update
方法来修复它:
class OwnerProfileSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.ReadOnlyField(source='user.id')
first_name = serializers.CharField(source='user.first_name')
last_name = serializers.CharField(source='user.last_name')
email = serializers.ReadOnlyField(source='user.email')
def update(self, instance, validated_data):
user = instance.user
# pprint(vars(user))
print(validated_data)
for updated_field in validated_data['user']:
value = validated_data['user'][updated_field]
setattr(user, updated_field, value)
for updated_field in validated_data:
if updated_field == 'user':
for user_field in validated_data['user']:
value = validated_data['user'][user_field]
setattr(user, user_field, value)
else:
value = validated_data[updated_field]
setattr(instance, updated_field, value)
user.save()
instance.save()
return instance
class Meta:
model = Profile
fields = (
'url',
'id',
....
但是,当我需要验证电子邮件地址更改时,这可能会在以后遇到问题。在这种情况下,根据@ Kostas'编写用户序列号。建议可能有用
答案 1 :(得分:-1)
一种选择是在您的应用中加入UserSerializer
,并使其可编辑。例如,这应该是这样的:
class OwnerProfileSerializer(serializers.HyperlinkedModelSerializer):
user = CustomUserSerializer(read_only=False).
这也会影响api响应的结构,但我相信这可以适用于你的情况。