Как я могу установить ID в JSON:API ответе Django REST Framework?

Я использую Django REST Framework JSON:API. Затем, я хочу установить ID в ответе.

Я знаю, что ответ получает ID из экземпляра модели Django. Но, если я устанавливаю экземпляр в сериализатор, пользовательские проверенные_данные не отображаются.

Пример

class Tag(models.Model):
    name = models.CharField(max_length=64, unique=True)
class TagSerializer(serializers.Serializer):
    name = serializers.CharField()
class TagDetailView(views.APIView):
    def get(self, request, pk):
        tag = Tag.objects.get(pk=pk)
        serializer = TagSerializer(data={"name": tag.name, "memo": "memo"})
        serializer.is_valid(raise_exception=True)
        return Response(data=serializer.data, status=200)
<
{
    "data": {
        "type": "TagDetailView",
        "id": 1,
        "attributes": {
            "name": "name",
            "memo": "memo"
        }
    }
}

As-Is


{
    "data": {
        "type": "TagDetailView",
        "id": null, //  I WANT TO SET THE ID HERE
        "attributes": {
            "name": "name",
            "memo": "memo"
        }
    }
}

Во-первых, вы передаете исходные данные сериализатора в ваш Response. На самом деле, вы не используете свой TagSerializer для сериализации данных из экземпляра модели в json.

Во-вторых, у вас модель Tag, поэтому попробуйте использовать serializers.ModelSerializer вместо serializers.Serializer.

Чтобы решить вашу проблему, я бы сделал следующее:

  1. Измените свой сериализатор
class TagSerializer(serializers.ModelSerializer):
    name = serializers.CharField()
    memo = serializers.SerializerMethodField(method_name="get_memo")  # if you want to add some custom field which is not in your model

    class Meta:
        model = Tag
        fields = "__all__"
   
    def get_memo(self, obj: Tag) -> str:
        return "memo"
  1. Немного измените свой APIView
from typing import Optional


class TagDetailView(views.APIView):
    def get(self, request, pk):
        tag: Optional[Tag] = Tag.objects.filter(pk=pk).first()
        if tag is None:
            return Response(data={}, status=404)
        data = TagSerializer(tag).data # passing instance of Tag to serializer
        return Response(data=data, status=200)

Итак, теперь в вашем ответе должно быть "id", поскольку мы предоставили fields = "__all__" для TagSerializer

Вернуться на верх