Как создать пользовательские представления API в Django Rest Framework

Я хочу создать пользовательское представление API на основе существующих данных.

models.py

class Practice(models.Model):
    practice_id = models.BigAutoField(primary_key=True)
    score = models.SmallIntegerField(null=True)
    correct = models.SmallIntegerField(null=True)
    wrong = models.SmallIntegerField(null=True)
    not_answered = models.SmallIntegerField(null=True)

    class Meta:
        managed = True
        db_table = 'practice'

    def __str__(self):
        return str(self.practice_id)

serializers.py

class PracticeSerializer(serializers.ModelSerializer):

    class Meta:
        model = Practice
        fields = ('practice_id',
                  'score',
                  'correct',
                  'wrong',
                  'not_answered',
                  )

views.py

@api_view(['GET'])
def practice_detail(request, pk):
    try: 
        practice = Practice.objects.get(pk=pk) 
    except Practice.DoesNotExist: 
        return JsonResponse({'message': 'The practice does not exist'}, status=status.HTTP_404_NOT_FOUND) 

    if request.method == 'GET': 
        exercises_serializer = PracticeSerializer(practice) 
        return JsonResponse(exercises_serializer.data)

С помощью приведенного выше кода я получаю результаты представления API следующим образом, используя id практики 485 :

/api/practice/485

{
    practice_id: 485,
    score: 10,
    correct: 2,
    wrong: 3,
    not_answered: 0,
}

Сейчас я хочу создать пользовательское представление API с результатом, как показано ниже :

{
    labels: ["Practice"],
    datasets: [
        {
            label: "Correct",
            data: [2],
        },
        {
            label: "Wrong",
            data: [3],
        },
        {
            label: "Not_answered",
            data: [0],
        }
    ]
}

Как это сделать?

Возможно ли достичь этого без создания новых моделей?

Определите формат в Serializer.to_representation() как документированный

.to_representation() - Переопределите это для поддержки сериализации, для операций чтения.

class PracticeSerializer(serializers.ModelSerializer):

    class Meta:
        model = Practice
        fields = ('practice_id',
                  'score',
                  'correct',
                  'wrong',
                  'not_answered',
                  )

    def to_representation(self, instance):
        """
        Object instance -> Dict of primitive datatypes.
        """
        return {
            "labels": ["Practice"],
            "datasets": [
                {
                    "label": "Correct",
                    "data": instance.correct,
                },
                {
                    "label": "Wrong",
                    "data": instance.wrong
                },
                {
                    "label": "Not_answered",
                    "data": instance.not_answered,
                }
            ]
        }

Выход:

$ curl http://127.0.0.1:8000/api/practice/485
{"labels": ["Practice"], "datasets": [{"label": "Correct", "data": 2}, {"label": "Wrong", "data": 3}, {"label": "Not_answered", "data": 0}]}
Вернуться на верх