【问题标题】:需要在 Django 中为我的 API 序列化自定义字段 AVG 注释
【发布时间】:2022-01-10 07:31:27
【问题描述】:

models.py

from django.db import models
from django.db.models import Avg
from users.models import UserProfile
from subjects.models import Subject


class Note(models.Model):
    id_user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name='user_note')
    id_subject = models.ForeignKey(Subject, on_delete=models.CASCADE, related_name='subject_note')
    exam_note = models.IntegerField()

    @property
    def average_note(self):
        if hasattr(self, '_average_note'):
            return self._average_note
        return Note.objects.aggregate(Avg('exam_note'))

这是我的笔记模型,我需要计算笔记平均值以将其序列化并发送请求响应

views.py

class AvgNoteViewSet(viewsets.ModelViewSet):
    serializer_class = AvgSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (NotePermissions,)

    def get_queryset(self):
        return Note.objects.all().annotate(_average_note=Avg('exam_note'))

这是我的 get_queryset 重新定义的方法来计算平均注释,但我只有一个查询结果的注释列表,如下所示: resques response

serializers.py

class AvgSerializer(serializers.ModelSerializer):
    """
    Serializes a notes AVG
    """

    average_note = serializers.SerializerMethodField()

    def get_average_note(self, obj):
        return obj.average_note

    class Meta:
        model = Note
        fields = ['average_note']

这是我的序列化器

我的意图是尝试从登录用户的考试笔记中获取平均值,所以我知道我需要尝试按 user_id ant 分组,然后汇总平均值。这是我查询时的 postgresql 表:notes_table

我的代码来自How to calculate average of some field in Django models and send it to rest API?,但我试图获得一些结果,例如运行以下查询:

SELECT avg(exam_note) 
FROM public.notes_note x
group by id_user_id

【问题讨论】:

    标签: django django-models django-views aggregate-functions django-serializer


    【解决方案1】:

    要添加 GROUP BY 功能,您只需将 values 添加到您的 get_queryset 方法中,如下所示:

    class AvgNoteViewSet(viewsets.ModelViewSet):
        serializer_class = AvgSerializer
        authentication_classes = (TokenAuthentication,)
        permission_classes = (NotePermissions,)
    
        def get_queryset(self):
            return Note.objects.all().values('id_user').annotate(_average_note=Avg('exam_note'))
    

    【讨论】:

    • 谢谢,这对我很有帮助,我需要像这样更改我的序列化程序:@staticmethod def get_average_note(obj): return obj['_average_note']
    猜你喜欢
    • 2020-07-19
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    相关资源
    最近更新 更多