1

this answerのメソッドを使用してプロファイルでユーザーモデルを拡張しようとしています。django restシリアライザで関連モデルのフィールドを変更します

私の考えは、ユーザーに関するリクエストが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) 

をそして、私のシリアライザは、次のようになりますようにfirst_nameを通り、私は所有者がまたuserオブジェクトのフィールドを変更できるようにしたいと思い

#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', 
     ) 

last_nameemail、など私は(例えば)発見していないが

DRFシリアライザドキュメントの

これをどのように達成できますか?可能であれば、すべての変更をプロファイルビュー/シリアライザで行い、ユーザーではないようにします。私はlast_name = serializers.CharField(source='user.last_name')ReadOnlyFieldを置き換え試験として

--EDIT--

。私はそれを更新しようとしたとき、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

1つのオプションは、お使いのアプリにUserSerializerを含めて編集可能にすることです。たとえば、これは次のようになります:

これは少しでもあなたの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の提案に従ったユーザシリアルサーキットを作成すると動作する可能性があります

関連する問題