You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django Rest Framework中如何基于Queryset返回自定义诊所数量结果?

实现方法当然有!我来给你一步步说明

你现在用的是Generic ListAPIView,要从返回出诊记录改成返回当日诊所访问统计数量,其实只需要重写视图的核心方法就行,下面给你两种可行的方案:

方案1:基于现有ListAPIView修改

既然你已经用了ListAPIView,我们可以直接重写它的list方法,替换默认的列表返回逻辑,改成统计结果:

from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from .models import DoctorVisit
from datetime import datetime

class TotalClinicView(ListAPIView):
    # 这里不需要原来的序列化器了,因为我们直接返回统计数据
    # serializer_class = DoctorVisitSerializer

    def get_queryset(self):
        # 先获取并校验请求参数
        slug = self.request.query_params.get('slug')
        date_str = self.request.query_params.get('date')
        
        if not slug or not date_str:
            raise ValidationError("slug和date参数为必填项")
        
        # 解析日期(注意格式要和前端传入的匹配,这里假设是dd-mm-yy)
        try:
            working_date = datetime.strptime(date_str, "%d-%m-%y").date()
        except ValueError:
            raise ValidationError("日期格式错误,请使用dd-mm-yy格式,例如:9-10-21")
        
        # 过滤出该医生当日的所有出诊记录
        return DoctorVisit.objects.filter(
            slug=slug,
            working_date__date=working_date
        )
    
    def list(self, request, *args, **kwargs):
        # 获取过滤后的查询集
        queryset = self.get_queryset()
        
        # 统计当日访问的不同诊所数量
        total_clinics = queryset.values('clinic').distinct().count()
        
        # 构造返回的统计数据
        response_data = {
            "doctor_name": queryset.first().doctor_name if queryset.exists() else "无出诊记录",
            "slug": self.request.query_params.get('slug'),
            "working_date": working_date.strftime("%Y-%m-%d"),  # 统一返回标准日期格式
            "total_clinics_visited": total_clinics
        }
        
        return Response(response_data)

方案2:改用更灵活的APIView

如果觉得用ListAPIView来返回单条统计数据有点“不搭”,也可以直接用基础的APIView来实现,逻辑会更直观:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from .models import DoctorVisit
from datetime import datetime

class TotalClinicView(APIView):
    def get(self, request):
        # 获取并校验参数
        slug = request.query_params.get('slug')
        date_str = request.query_params.get('date')
        
        if not slug or not date_str:
            raise ValidationError("slug和date参数为必填项")
        
        # 解析日期
        try:
            working_date = datetime.strptime(date_str, "%d-%m-%y").date()
        except ValueError:
            raise ValidationError("日期格式错误,请使用dd-mm-yy格式")
        
        # 过滤出诊记录
        visits = DoctorVisit.objects.filter(
            slug=slug,
            working_date__date=working_date
        )
        
        # 统计诊所数量
        total_clinics = visits.values('clinic').distinct().count()
        
        # 返回结果
        return Response({
            "doctor_name": visits.first().doctor_name if visits.exists() else "无出诊记录",
            "slug": slug,
            "working_date": working_date.strftime("%Y-%m-%d"),
            "total_clinics_visited": total_clinics
        })

关键说明:

  • 日期解析:一定要确保strptime的格式和前端传入的日期格式匹配,如果前端是mm-dd-yy(比如9-10-21代表2021年9月10日),就把格式改成"%m-%d-%y",不然会解析失败。
  • 统计逻辑:values('clinic').distinct().count()的作用是先取出所有记录的clinic字段,去重后统计数量,这样就能得到该医生当日访问的不同诊所总数。
  • 异常处理:加入了参数缺失和日期格式错误的校验,返回DRF标准的错误响应,更符合API规范。

内容的提问来源于stack exchange,提问作者shankarj67

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:38:46