Django DRF - Возврат всего профиля другого пользователя в вызове API

У меня есть UserSerializer (я использовал модель CustomUser)

class UserSerializer(serializers.ModelSerializer):
    class Meta:
      model = CustomUser
      fields = ['id', 'first_name', 'last_name', 'email', 'is_typeA', 'is_typeB']
      read_only_fields = ['id', 'email', 'is_typeA', 'is_typeB']

У меня есть модель профиля для каждого типа пользователя, а также сериализатор.

class TypeASerializer(serializers.ModelSerializer):
  user = UserSerializer()
  class Meta:
    model = TypeAProfile
    fields = ['user_id','user','course', 'ndex', 'created_at']
    read_only_fields = ['id', 'created_at']

class TypeBSerializer(serializers.ModelSerializer):
  user = UserSerializer()
  class Meta:
    model = TypeBProfile
    fields = ['user_id', 'user', 'course', 'rating', 'created_at']
    read_only_fields = ['id', 'created_at', 'rating']

У меня есть конечная точка для получения профиля вошедшего пользователя.

class MyProfile(APIView):
  def get(self, request, *args, **kwargs):
    serializer = get_user_profile(request.user)
    return Response(serializer.data)
  
  def patch(self, request, *args, **kwargs):
    if request.user.is_typeA:
      typeauser = TypeAProfile.objects.get(user_id=request.user.id)
      user_updates = request.data.pop('user')
      serializer = TypeASerializer(typeauser, data=request.data, partial=True)
      serializer.is_valid(raise_exception=True)
      serializer.save()
      user_serializer = UserSerializer(typea.user, data=user_updates, partial=True)
      user_serializer.is_valid(raise_exception=True)
      user_serializer.save()
      return Response(serializer.data)
    elif request.user.is_typea:
      typebuser = TypeBProfile.objects.get(user_id=request.user.id)
      user_updates = request.data.pop('user')
      serializer = TypeBSerializer(typebuser, data=request.data, partial=True)
      serializer.is_valid(raise_exception=True)
      serializer.save()
      user_serializer = UserSerializer(typebuser.user, data=user_updates, partial=True)
      user_serializer.is_valid(raise_exception=True)
      user_serializer.save()
      return Response(serializer.data)
    serializer = UserSerializer(request.user, data=request.data, partial=True)
    serializer.is_valid(raise_exception=True)
    serializer.save()
    return Response(serializer.data)

Мой конечной точкой является : /profile.

Возврат:

{
    "user_id": 1,
    "user": {
        "id": 1,
        "first_name": "John",
        "last_name": "Smith",
        "email": "email@email.com",
        "is_typeA": false,
        "is_typeB": true
    },
    "course": "Udemy-123",
    "index": 2
    "created_at": "2022-04-12T01:43:49.091825Z"
}

Я добавил модель Избранное - это для того, чтобы пользователи могли добавлять друг друга в избранное. Пользователи типа А могут добавлять в избранное пользователей типа В.

class Favourite(models.Model):
    typeA = models.ForeignKey(to=TypeAProfile, on_delete=models.CASCADE, related_name='favourites')
    typeB = models.ForeignKey(to=TypeBProfile, on_delete=models.CASCADE, related_name='fans')
    
    def __str__(self):
        return str(self.typeB)

Проблема:

Я пытаюсь вернуть список избранного при вызове Profile API, но пока не могу добиться, чтобы это имело смысл.

Я добавил избранное в профиль TypeA Serializer:

class TypeASerializer(serializers.ModelSerializer):
  user = UserSerializer()
  favourites = serializers.StringRelatedField(many=True)

  class Meta:
    model = TypeAProfile
    fields = ['user_id','user', 'course', 'handicap_index', 'created_at', 'favourites']
    read_only_fields = ['id', 'created_at']

И он возвращает электронные письма пользователей, которые являются избранными, но я хочу, чтобы он возвращал весь их профиль.

{
    "user_id": 1,
    "user": {
        "id": 1,
        "first_name": "John",
        "last_name": "Smith",
        "email": "email@email.com",
        "is_typeA": false,
        "is_typeB": true
    },
    "course": "Udemy-123",
    "index": 2,
    "created_at": "2022-04-12T01:43:49.091825Z",
    "favourites": [
    "test1@email.com",
    "test2@email.com"
    ]
}

Если вы хотите показать только favourites, а не fans, вы можете просто написать:

class TypeASerializer(serializers.ModelSerializer):
  user = UserSerializer()
  favourites = TypeBSerializer(many=True)

  class Meta:
    model = TypeAProfile
    fields = ['user_id','user', 'course', 'handicap_index', 'created_at', 'favourites']
    read_only_fields = ['id', 'created_at']

Вместо этого, если вы хотите показывать также fans, вам нужно перепроектировать ваши сериализаторы, чтобы избежать рекурсивной проблемы:

class TypeASerializerWithoutFavourites(serializers.ModelSerializer):
  user = UserSerializer()
  class Meta:
    model = TypeAProfile
    fields = ['user_id','user','course', 'ndex', 'created_at']
    read_only_fields = ['id', 'created_at']

class TypeBSerializerWithoutFans(serializers.ModelSerializer):
  user = UserSerializer()
  class Meta:
    model = TypeBProfile
    fields = ['user_id', 'user', 'course', 'rating', 'created_at']
    read_only_fields = ['id', 'created_at', 'rating']

class TypeASerializer(TypeASerializerWithoutFavourites):
   favourites = TypeBSerializerWithoutFans(many=True)
  
   class Meta(TypeASerializerWithoutFavourites.Meta):
      fields = TypeASerializerWithoutFavourites.Meta.fields + ['favourites']


class TypeBSerializer(TypeBSerializerWithoutFans):
   fans = TypeASerializerWithoutFavourites(many=True)
  
   class Meta(TypeBSerializerWithoutFans.Meta):
      fields = TypeBSerializerWithoutFans.Meta.fields + ['fans']
Вернуться на верх