首页 > 其他分享 >饮冰三年-人工智能-Django淘宝拾遗-76-DRF实现按月统计以及GroupConcat使用

饮冰三年-人工智能-Django淘宝拾遗-76-DRF实现按月统计以及GroupConcat使用

时间:2022-12-13 17:14:04浏览次数:77  
标签:GroupConcat models profession Django 76 score exams total id

饮冰三年-人工智能-Django淘宝拾遗-75-数据准备

一、实现按周期统计是一个很常用的功能,在使用python的DRF中也可以实现该功能。

按照周进行汇总
SELECT DATE_FORMAT(exams_dat,"%Y-%u") as weeks_month, profession_id, Sum('score_total')
FROM tb_production_statistics
GROUP BY profession_id,weeks_month 
按照月进行汇总
SELECT DATE_FORMAT(exams_dat,"%Y-%m") as weeks_month, profession_id, Sum('score_total')
FROM tb_production_statistics
GROUP BY profession_id,weeks_month 
SQL表示形式
按周进行汇总
from django.db.models.functions import TruncWeek,TruncMonth
Article.objects
.annotate(week_mont=TruncWeek('exams_date'))  # Truncate to month and add to select list
.values('profession_id')  # Group By profession_id
.annotate(score_total=Sum('score_total'))  # Select the sum of the grouping
.values('week_mont', 'profession_id')  # (might be redundant, haven't tested) select month and count
按月进行汇总
from django.db.models.functions import TruncWeek,TruncMonth
Article.objects
.annotate(week_mont=TruncMonth('exams_date'))  # Truncate to month and add to select list
.values('profession_id')  # Group By profession_id
.annotate(score_total=Sum('score_total'))  # Select the sum of the grouping
.values('week_mont', 'profession_id')  # (might be redundant, haven't tested) select month and count
Django表示形式

二、GroupBy之后部分防止数据信息,可以把某个字段拼接起来

SELECT `tb_score_summary`.`profession_id`, MIN(`tb_score_summary`.`exams_date`) AS `exams_date`, SUM(`tb_score_summary`.`score_total`) AS `score_total`, 
GROUP_CONCAT(`tb_score_summary`.`total_concat` SEPARATOR ";") AS `total_concat` 
FROM `tb_score_summary` 
GROUP BY `tb_score_summary`.`profession_id`  
SQL表示形式

 在Django中需要自定义一个GroupConcat类

class GroupConcat(Aggregate):
    function = 'GROUP_CONCAT'
    template = '%(function)s(%(distinct)s%(expressions)s%(ordering)s%(separator)s)'

    def __init__(self, expression, distinct=False, ordering=None, separator=';', **extra):
        super(GroupConcat, self).__init__(
            expression,
            distinct='DISTINCT ' if distinct else '',
            ordering=' ORDER BY %s' % ordering if ordering is not None else '',
            separator=' SEPARATOR "%s"' % separator,
            output_field=CharField(),
            **extra)
GroupConcat
按周进行汇总,并且把total_concat拼接
from django.db.models.functions import TruncWeek,TruncMonth
Article.objects
.annotate(week_mont=TruncWeek('exams_date'))  # Truncate to month and add to select list
.values('profession_id')  # Group By profession_id
.annotate(score_total=Sum('score_total'), total_concat=GroupConcat('total_concat', separator=';')
)  # Select the sum of the grouping
.values('week_mont', 'profession_id')  # (might be redundant, haven't tested) select month and count
按月进行汇总,并且把total_concat拼接
from django.db.models.functions import TruncWeek,TruncMonth
Article.objects
.annotate(week_mont=TruncMonth('exams_date'))  # Truncate to month and add to select list
.values('profession_id')  # Group By profession_id
.annotate(score_total=Sum('score_total'), total_concat=GroupConcat('total_concat', separator=';')
)  # Select the sum of the grouping
.values('week_mont', 'profession_id')  # (might be redundant, haven't tested) select month and count
Django表示形式 

三、实现按月统计不同专业的总成绩,并把每个学生的考试总成绩拼接再一起

from django.urls import path, re_path

from api_service.report.views import ScoreListView, ScoreDetailView, ScoreSummaryListView

urlpatterns = [
    path('score_summary/list', ScoreSummaryListView.as_view()),  # 成绩汇总列表
]
url.py
from django.db import models


class ScoreModels(models.Model):
    gender = models.SmallIntegerField(verbose_name='性别')
    profession_id = models.IntegerField(verbose_name='专业id')
    profession_name = models.CharField(max_length=255, verbose_name='专业名称')
    course_id = models.IntegerField(verbose_name='课程id')
    course_name = models.CharField(max_length=255, verbose_name='课程名称')
    student_id = models.IntegerField(verbose_name='学生ID')
    student_name = models.CharField(max_length=255, verbose_name='学生名称')
    exams_version = models.IntegerField(verbose_name='考试版本')
    exams_date = models.DateField(verbose_name='考试日期')
    score_total = models.BigIntegerField(verbose_name='考试成绩')
    add_time = models.DateTimeField(verbose_name='创建时间')
    modify_time = models.DateTimeField(verbose_name='修改时间')

    class Meta:
        managed = True
        db_table = 'tb_score'
        verbose_name = '考试成绩表'


class ScoreSummaryModels(models.Model):
    profession_id = models.IntegerField(verbose_name='专业id')
    exams_version = models.IntegerField(verbose_name='考试版本')
    exams_date = models.DateField(verbose_name='考试日期')
    score_total = models.BigIntegerField(verbose_name='考试成绩')
    total_concat = models.TextField(verbose_name='以{标注员:总成绩}组成的json字符串')
    add_time = models.DateTimeField(verbose_name='创建时间')
    modify_time = models.DateTimeField(verbose_name='修改时间')

    class Meta:
        managed = True
        db_table = 'tb_score_summary'
        verbose_name = '考试成绩汇总表'
model.py
import django_filters
import logging
from django_filters import rest_framework as filter_set

from api_service.report.models import ScoreModels, ScoreSummaryModels

from api_service.report.public_methods import date_range_filter

logger = logging.getLogger("api_service")


class ScoreFilter(filter_set.FilterSet):
    profession_id = filter_set.CharFilter(lookup_expr='exact')
    gender = django_filters.BaseInFilter(lookup_expr='in')
    exams_date = filter_set.CharFilter(field_name='exams_date', method=date_range_filter)

    class Meta:
        models = ScoreModels
        fields = ('profession_id', 'gender', 'exams_date')


class ScoreSummaryFilter(filter_set.FilterSet):
    profession_id = filter_set.CharFilter(lookup_expr='exact')
    exams_date = filter_set.CharFilter(field_name='exams_date', method=date_range_filter)

    class Meta:
        models = ScoreSummaryModels
        fields = ('profession_id', 'exams_date')
filters.py
class ScoresSummarySerializer(serializers.ModelSerializer):
    class Meta:
        model = ScoreSummaryModels
        fields = ('profession_id', 'exams_date', 'score_total', 'total_concat',)

    def to_representation(self, instance):
        data = super().to_representation(instance)
        period_type_no = self.context['request'].query_params.get('period_type_no')

        if period_type_no == str(PeriodType.PERIOD_TYPE_CODE_MONTH):
            cur_year = datetime.strptime(data['exams_date'], '%Y-%m-%d').year
            cur_month = datetime.strptime(data['exams_date'], '%Y-%m-%d').month
            data['exams_date'] = "%d年%d月" % (cur_year, cur_month)

        return data
serializers.py
class ScoreSummaryListView(ListAPIView):
    queryset = ScoreSummaryModels.objects.all()
    serializer_class = ScoresSummarySerializer
    filter_backends = (filters.OrderingFilter, DjangoFilterBackend,)
    filter_class = ScoreSummaryFilter
    pagination_class = StandardBasePagination

    source_summary_list_values = ('profession_id', 'exams_date', 'score_total', 'total_concat',)

    def filter_queryset(self, queryset):
        for backend in list(self.filter_backends):
            queryset = backend().filter_queryset(self.request, queryset, self)
        if queryset.exists():
            params = self.request.query_params
            period_type_no = params.get('period_type_no')
            if period_type_no == str(PeriodType.PERIOD_TYPE_CODE_WEEK):
                period_type_str = "TruncWeek('exams_date')"
            elif period_type_no == str(PeriodType.PERIOD_TYPE_CODE_MONTH):
                period_type_str = "TruncMonth('exams_date')"
            elif period_type_no == str(PeriodType.PERIOD_TYPE_CODE_DAY):
                period_type_str = "TruncDay('exams_date')"
            queryset = self.statistic_by_period(queryset, period_type_str)
        return queryset

    def statistic_by_period(self, queryset, period_type):
        queryset = queryset.annotate(week_month=eval(period_type)) \
            .values("profession_id", ) \
            .annotate(
            exams_date=Min('exams_date'),
            score_total=Sum('score_total'),
            total_concat=GroupConcat('total_concat', separator=';')
        ).values(*self.source_summary_list_values)
        return queryset
view.py
class GroupConcat(Aggregate):
    function = 'GROUP_CONCAT'
    template = '%(function)s(%(distinct)s%(expressions)s%(ordering)s%(separator)s)'

    def __init__(self, expression, distinct=False, ordering=None, separator=';', **extra):
        super(GroupConcat, self).__init__(
            expression,
            distinct='DISTINCT ' if distinct else '',
            ordering=' ORDER BY %s' % ordering if ordering is not None else '',
            separator=' SEPARATOR "%s"' % separator,
            output_field=CharField(),
            **extra)
GroupConcat

 

 

标签:GroupConcat,models,profession,Django,76,score,exams,total,id
From: https://www.cnblogs.com/YK2012/p/15968931.html

相关文章

  • 饮冰三年-人工智能-Django淘宝拾遗-83-migrations文件
    一、migrations文件维护我们使用Django框架时通过ORM维护数据模型,会碰到一个问题生成的migrations文件越来愈多,这些文件如何更好的进行代码维护。1:官方说明官方建议提交......
  • 【Django】orm 查询格式化 日期时间
    1.mysql数据库models.TerminalInfo.objects.filter(status=True).extra( select={'created_at':'date_format(created_at,"%%Y-%%m-%%d%%H:%%i:%%s")'})[ page_inf......
  • 第一章:手写简易的web框架,了解Django的原理
    手写一个简单的web框架纯手撸简易版的web框架importsocket#括号后面什么都不加默认tcp协议server=socket.socket()#访问地址server.bind(('127.0.0.1',8080)......
  • 可视化界面之数据增删改查、django请求生命周期图、django路由层、反向解析
    可视化界面之数据增删改查django请求生命周期流程图django路由层反向解析可视化界面之数据增删改查建表建表、加索引可以体现程序员的工作经验。建表......
  • Django框架三
    Django框架(三)Django请求生命周期流程图扩展知识点缓存数据库 浏览器向后端发送请求,在经过Django中间件之后,会先从缓存数据库寻找数据,如果没有则向后端数据库要数......
  • django无名分组和反向解析
    django请求生命周期流程图当客户端浏览器访问django后端时django框架中发生了哪些事情呢?客户端请求服务端时将客户端请求的各种数据和信息进行整理。应用程序则负责具体......
  • Django-路由层、反向解析
    1.Django请求生命周期流程图1.路由层、视图层、模板层、模型层、组件、BBS项目2.django路由层1.路由匹配:'''当我们输入一个地址时,接口后面的/不用输入,也可以自动跳......
  • P2762 太空飞行计划问题
    P2762太空飞行计划问题如果我的钱全部都流过去了,那不就相当于没有挣钱吗#include<bits/stdc++.h>usingnamespacestd;constintinf=1e9;constintN=155;consti......
  • django_应用及分布式路由
    一、应用的定义1、应用在Django中是一个独立的业务模块,可以包含自己的路由、视图、模板、模型。例如如下图所示,一个资讯类网站中会有不同的模块,如果所有的模......
  • Django之数据增删改查、Django请求生命周期流程图、Django路由层(路由匹配、转换器、正
    今日内容详细可视化界面之数据增删改查针对数据对象主键字段的获取可以使用更加方便的obj.pk获取在模型类中定义__str__方法可以在数据对象被执行打印操作的时候方......