Как я могу установить 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
.
Чтобы решить вашу проблему, я бы сделал следующее:
- Измените свой сериализатор
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"
- Немного измените свой 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