1

我试图用this answer中的方法扩展用户模型。在Django休息序列化器中修改相关模型的字段

我的想法是只发送一个关于用户的请求到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_namelast_name,email

但是我还没有找到一个(例如)ReadWriteField在DRF序列化器文档中。

我怎么能做到这一点?如果可能的话,我希望所有修改都通过配置文件视图/序列化程序而不是用户来完成。

- 编辑 -

作为测试我与last_name = serializers.CharField(source='user.last_name')取代ReadOnlyField。当我试图更新它,DRF给了我这个错误:

The .update() method does not support writable dotted-source fields by default. Write an explicit .update() method for serializer profiles.serializers.OwnerProfileSerializer , or set read_only=True on dotted-source serializer fields.

所以看起来我可以实现我自己的update方法。但我不知道如何继续。

回答

-1

一种选择是将您的UserSerializer包含在您的应用中,并使其可编辑。例如,这应该是这样的:

class OwnerProfileSerializer(serializers.HyperlinkedModelSerializer): 
    user = CustomUserSerializer(read_only=False). 

这也将影响到有点您的API响应的结构,但我相信这可以在你的情况下工作。

+0

由于我没有使用自定义用户模型,我只需制作CustomUserSerializer并将其放入'profiles.serializers'? – sonarforte

+0

是的,只要你保持一个好的代码结构来记住它就在那里就没事了 –

0

我设法在串行扩展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的建议编写用户序列器可能会工作

相关问题