如何将Django中四个聚合功能的GET视图合并为单个视图?
合并多个聚合GET端点到单个Django视图
完全可以将四个聚合逻辑整合到单个视图中,核心是通过URL传递聚合类型参数,在视图内根据参数执行对应逻辑。以下是具体实现方案:
一、修正URL配置
你之前的re_path混用了path语法(<str:id>),导致路由匹配失败。改用纯正则语法编写路由:
from django.urls import path, re_path urlpatterns = [ path('medidores/', MedidorView.as_view()), path('mediciones/', MedicionView.as_view()), # 统一聚合路由:匹配聚合类型+ID re_path(r'^medicion/(?P<aggregation>max|min|sum|avg)/(?P<id>[^/]+)/$', MedicionAggregateView.as_view()), # 保留旧路由(可选,用于逐步迁移) path('medicion_max/<str:id>', MedicionMaxView.as_view()), path('medicion_min/<str:id>', MedicionMinView.as_view()), path('medicion_total/<str:id>', MedicionTotalView.as_view()), path('medicion_prom/<str:id>', MedicionPromedioView.as_view()) ]
路由说明
(?P<aggregation>max|min|sum|avg):命名分组,限定聚合类型只能是这四个值(?P<id>[^/]+):匹配任意非斜杠字符作为ID,避免路由截断- 末尾
/$:确保完整匹配URL,防止部分匹配导致的错误
二、编写整合后的视图类
创建统一视图,通过字典映射聚合类型到对应函数,避免重复代码:
from django.db.models import Max, Min, Sum, Avg from django.http import JsonResponse from django.views import View class MedicionAggregateView(View): # 聚合类型与函数的映射表 AGG_FUNC_MAP = { 'max': Max, 'min': Min, 'sum': Sum, 'avg': Avg } def get(self, request, aggregation, id): # 验证聚合类型合法性 agg_func = self.AGG_FUNC_MAP.get(aggregation) if not agg_func: return JsonResponse({'error': '无效的聚合类型'}, status=400) # 执行聚合查询并返回结果 result = Medicion.objects.filter(medidor=id).aggregate(agg_func('consumo_kwh')) return JsonResponse(result)
三、测试访问
现在可以通过以下标准化URL访问聚合接口:
- 最大值:
/medicion/max/[你的ID]/ - 最小值:
/medicion/min/[你的ID]/ - 总和:
/medicion/sum/[你的ID]/ - 平均值:
/medicion/avg/[你的ID]/
四、可选:兼容旧路由(逐步迁移)
如果需要保留旧路由的可用性,可以让旧视图复用新视图的逻辑:
class MedicionMaxView(View): def get(self, request, id): return MedicionAggregateView.as_view()(request, aggregation='max', id=id) # 同理处理MedicionMinView、MedicionTotalView、MedicionPromedioView
内容的提问来源于stack exchange,提问作者Juan Manuel Amato
相关产品推荐
相关产品推荐

