DRF分页接口下,如何获取活动场地筛选列表?
解决方案
完全不需要请求所有活动数据,给你几个实用的实现方式:
1. 新增独立的场地列表API接口
这是最直观的方案:单独写一个接口专门返回所有可用的场地选项,直接从数据库查询去重后的场地;如果你的项目里已经有单独的Venue模型(关联到Event),直接查询该模型即可,效率更高。
代码示例:
序列化器
from rest_framework import serializers from .models import Event # 若有Venue模型则替换为Venue class VenueSerializer(serializers.Serializer): # 基于Event模型取去重场地的写法 venue = serializers.CharField() # 若有独立Venue模型,直接序列化: # class Meta: # model = Venue # fields = ('id', 'name')
视图
from rest_framework.views import APIView from rest_framework.response import Response from .models import Event from .serializers import VenueSerializer class VenueListView(APIView): def get(self, request): # 从Event中提取去重并排序的场地 venues = Event.objects.values_list('venue', flat=True).distinct().order_by('venue') # 序列化返回 serializer = VenueSerializer([{'venue': v} for v in venues], many=True) return Response(serializer.data)
配置URL
from django.urls import path from .views import VenueListView urlpatterns = [ # 其他接口... path('venues/', VenueListView.as_view(), name='venue-list'), ]
前端只需在页面加载时请求一次这个接口,就能拿到所有场地选项,和活动分页接口完全独立。
2. 在分页接口中附加场地列表
如果不想新增接口,可以自定义DRF的分页类,在返回分页数据的同时,额外带上场地列表。这样前端请求分页数据时,一次就能拿到表格数据和筛选选项。
代码示例:
from rest_framework.pagination import PageNumberPagination class EventPagination(PageNumberPagination): page_size = 10 def get_paginated_response(self, data): # 附加去重排序后的场地列表 venues = self.queryset.values_list('venue', flat=True).distinct().order_by('venue') return Response({ 'count': self.page.paginator.count, 'next': self.get_next_link(), 'previous': self.get_previous_link(), 'results': data, 'venues': list(venues) })
然后在活动列表视图中使用这个分页类:
from rest_framework import generics from .models import Event from .serializers import EventSerializer class EventListView(generics.ListAPIView): queryset = Event.objects.all() serializer_class = EventSerializer pagination_class = EventPagination
3. 缓存场地列表(优化性能)
如果场地数据不频繁更新,可以给场地列表加缓存,避免每次请求都查询数据库。比如用Django的缓存框架:
from django.core.cache import cache from rest_framework.views import APIView from rest_framework.response import Response from .models import Event class VenueListView(APIView): def get(self, request): # 先查缓存 venues = cache.get('event_venues') if not venues: venues = list(Event.objects.values_list('venue', flat=True).distinct().order_by('venue')) # 缓存1小时,可根据实际调整过期时间 cache.set('event_venues', venues, 3600) return Response({'venues': venues})
内容的提问来源于stack exchange,提问作者bodger
相关产品推荐
相关产品推荐

