一、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()
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