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']