在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
相关产品推荐
相关产品推荐

