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

Django Rest Framework自定义ViewSet实现按年份查询节假日

完善DRF按年份查询节假日的自定义视图实现

我来帮你把这个按年份查询节假日的视图补全并优化,咱们一步步来:

1. 补全基础配置与代码细节

首先你的ViewSet需要指定queryset和serializer_class(这是GenericViewSet的必填项),同时补全代码里的拼写遗漏,再完善参数校验和响应逻辑:

from rest_framework import mixins, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from datetime import date

# 请替换成你实际的模型和序列化器
from .models import Holiday
from .serializers import HolidaySerializer

class HolidayViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = Holiday.objects.all()
    serializer_class = HolidaySerializer

    @action(methods=['get'], detail=False)
    def year(self, request):
        # 从请求参数获取年份,默认使用当前年份
        year_param = request.query_params.get('year', date.today().year)
        
        # 校验年份参数的有效性
        try:
            year = int(year_param)
            # 可根据业务需求添加年份范围限制,比如只允许查询2000年至未来5年的节假日
            if not (2000 <= year <= date.today().year + 5):
                return Response({"error": "年份超出合理查询范围"}, status=400)
        except ValueError:
            return Response({"error": "请传入有效的数字年份"}, status=400)
        
        # 筛选对应年份的节假日
        public_holidays = self.get_queryset().filter(date__year=year)
        
        # 处理分页逻辑
        page = self.paginate_queryset(public_holidays)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        
        # 不分页时直接返回全部结果
        serializer = self.get_serializer(public_holidays, many=True)
        return Response(serializer.data)

2. 关键优化点说明

  • 替换旧版装饰器:把过时的@list_route()换成DRF 3.10+推荐的@action(methods=['get'], detail=False),detail=False表示这是列表级别的接口,而非单条数据的详情接口。
  • 灵活的参数获取:采用query_params获取年份参数,前端可以通过/api/holidays/year/?year=2024的方式请求,比路径参数更灵活;如果需要用路径传参(比如/api/holidays/year/2024/),可以修改方法定义为def year(self, request, year):并配置对应路由。
  • 参数校验:增加了年份格式和范围校验,避免无效参数导致数据库查询异常,同时返回友好的错误提示。
  • 完整响应逻辑:兼容分页与不分页场景,若你开启了DRF全局分页配置,会自动返回分页结构;否则直接返回全部数据。

3. 路由配置(可选)

如果使用DRF的DefaultRouter,它会自动为@action生成路由,默认访问路径是/holidays/year/。若想自定义路径,可以在装饰器中添加url_path参数,比如@action(methods=['get'], detail=False, url_path='by-year'),此时访问路径变为/holidays/by-year/。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:49:20