• 15 Django REST Framework 给api添加自定义搜索条件


    一、ListModelMixin源码

    # 源码
    
    class ListModelMixin(object):
        """
        List a queryset.
        """
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)

    二、解决方法:

    01-增加筛选条件 - 重写ListModelMixin的list方法

    注:不会改变原有的筛选条件的方式 :queryset = self.filter_queryset(self.queryset);

      如果放弃原有的筛选条件的方式: queryset = self.queryset  都重新做筛选。

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.queryset)
        ...
        # 增加筛选条件
        ...
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
    
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    示例:

    class RoomReservationViewSet(viewsets.ModelViewSet):
        """
            list:
                返回列出所有 会议室预定 数据.
                检索方式:
                  官网地址:https://github.com/miki725/django-url-filter
                      单条件检索:/api/?work_status=已完成&&work_type=维修
                      单字段多条件检索: /api/?work_status__in=已完成,新建
                      非字段检索: /api/?work_status__icontains!=待审批
                      外键字段检索:/api/?approval_team__name=审批组
                      时间检索: start_time__range
                          /api/office_room/?start_time__range=2019-04-11,2019-04-12
                          /api/office_room/?start_time__year=2019
                          /api/office_room/?start_time__gt=2019-04-11
    
            create:
                创建一条 会议室预定 数据.
    
            retrieve:
                返回一个 会议室预定 实例.
    
            update:
                更新一条 会议室预定 数据.
    
            partial_update:
                更新 会议室预定 的部分字段.
    
            delete:
                删除一条 会议室预定 数据.
        """
        queryset = models.RoomReservation.objects.all().order_by('-riid')
        pagination_class = StandardResultsSetPagination
        serializer_class = RoomReservationSerializer
        # 使用过滤器
        filter_backends = (DjangoFilterBackend, filters.SearchFilter,)
    
        authentication_classes = ()
        permission_classes = (AllowAny, )
        # 定义需要使用过滤器的字段
        filter_fields = ('riid', 'roomid', 'start_time', 'end_time', 'res_user', 'com_name', 'room_status', 'res_time')
    
        search_fields = ('riid', 'roomid', 'start_time', 'end_time', 'res_user', 'com_name', 'room_status', 'res_time')
    
        def list(self, request, *args, **kwargs):
            from rest_framework import mixins
            # queryset = mixins.ListModelMixin.list(request, *args, **kwargs).queryset
            time_now = datetime.datetime.now()
            room_obj = RoomReservation.objects.all()
            # 更新 会议室状态
            for i in room_obj:
                if i.start_time < time_now < i.end_time:
                    i.room_status = '使用中'
                    i.save()
                elif time_now > i.end_time:
                    i.room_status = '已结束'
                    i.save()
    
            room_num = request.GET.get('room_num')
            start_time = request.GET.get('start_time')
            end_time = request.GET.get('end_time')
            room_id = request.GET.get('room_id')
            room_status = request.GET.get('room_status')
            # queryset = self.queryset
            queryset = self.filter_queryset(self.queryset)
            if room_id:
                queryset = models.RoomReservation.objects.filter(roomid__room_num=room_id).order_by('-riid')
            if room_status:
                queryset = models.RoomReservation.objects.filter(room_status=room_status).order_by('-riid')
    
            room_num_obj = models.RoomNumber.objects.filter(room_num=room_num).first()
            # lt 小于  gt 大于
            if room_num_obj:
                queryset = models.RoomReservation.objects.filter(roomid=room_num_obj).order_by('-riid')
            if room_num_obj and start_time and end_time:
                queryset = models.RoomReservation.objects.filter(roomid=room_num_obj).filter(start_time__lt=end_time).filter(end_time__gt=start_time).order_by('-riid')
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
    
        def perform_create(self, serializer):
            instance = serializer.save()
            instance.res_time = datetime.datetime.now()
            instance.save()
    views.py

     02-重写filter_queryset方法

    注意:此处 worksheet_no 字段 为 外键字段;

    def filter_queryset(self, queryset):
        queryset = super(TasksViewSet, self).filter_queryset(self.queryset)
        worksheet_no = self.request.query_params.get('worksheet_no', None)
        print('worksheet_no', worksheet_no)
        if worksheet_no:
            worksheet_no_instance = WorkSheet.objects.filter(work_no=worksheet_no).first()
            print('worksheet_no_instance', worksheet_no_instance)
            queryset = self.queryset.filter(worksheet_no=worksheet_no_instance)
    
        return queryset
  • 相关阅读:
    已解决:No 'Access-Control-Allow-Origin'跨域问题
    (转 )聊聊GIS中的坐标系|再版
    CentOs如何挂载硬盘(手把手教你 )
    CentOS如何挂载硬盘
    CentOS7 复制文件夹和移动文件夹
    centos中怎么查看一个文件的创建时间
    vue项目报错Trailing spaces not allowed.
    (转)Vue框架Element UI教程-安装环境搭建(一)
    windows 根据端口查看进行PID 并杀掉进程
    完美解决CentOS8 yum安装AppStream报错,更新yum后无法makecache的问题
  • 原文地址:https://www.cnblogs.com/pgxpython/p/10761022.html
Copyright © 2020-2023  润新知