Django_filters:如何基于用户访问的Venue ID用ModelChoiceFilter过滤分类
问题解决:基于当前Venue动态加载django_filters分类选项
核心问题
你需要实现两个关键需求:
- 分类由对应Venue对象提供,仅对该Venue的用户可见
- 筛选器只显示当前访问的Venue页面相关的分类
当前的问题是filter.py无法获取当前页面的Venue ID,导致ModelChoiceFilter无法加载正确的分类查询集。
解决方案
1. 修改filter.py:动态传递Venue参数
FilterSet的字段queryset不能在定义时固定,需要在初始化时根据当前Venue动态生成。通过重写__init__方法实现:
import django_filters from django import forms from .models import Catalogue, Venue class CatalogueFilter(django_filters.FilterSet): product_title = django_filters.CharFilter( label='', lookup_expr='icontains', widget=forms.widgets.TextInput(attrs={'placeholder':'Long list! Type the name of your product here.'}) ) # 先初始化空查询集,后续动态赋值 type = django_filters.ModelChoiceFilter(queryset=Catalogue.objects.none()) class Meta: model = Catalogue fields = ['product_title','type'] def __init__(self, *args, **kwargs): # 取出传入的venue参数,避免传递给父类构造方法 self.venue = kwargs.pop('venue') super().__init__(*args, **kwargs) # 动态生成当前Venue对应的分类查询集 # 注意:如果type是外键到独立的Category模型,需调整为 Category.objects.filter(catalogue__venue=self.venue).distinct() self.filters['type'].queryset = Catalogue.objects.filter(venue=self.venue).values_list('type', flat=True).distinct()
2. 修改views.py:初始化FilterSet时传入Venue对象
在视图中初始化FilterSet时,把当前获取到的Venue对象传递进去:
def show_venue(request, venue_id): if request.method == "POST" and 'btnreview_form' in request.POST: # 保留原POST逻辑不变 form = CatalogueReviewForm(request.POST) if form.is_valid(): data = form.save(commit=False) data.product_id = venue_id data.venue_id = request.POST.get('venue_id') data.user_id = request.user.id data.save() ven_id = request.POST.get('venue_id') return HttpResponseRedirect(ven_id) else: venue = Venue.objects.get(pk=venue_id) menu = Catalogue.objects.filter(venue=venue_id) categories = Catalogue.objects.filter(venue=venue_id).order_by('category_order') # 初始化FilterSet时传入venue参数 myFilter = CatalogueFilter(request.GET, queryset=categories, venue=venue) categories = myFilter.qs
关键说明
- 原写法在FilterSet定义阶段就试图获取Venue ID,但此时没有请求上下文,无法获取当前页面的Venue信息。必须在初始化FilterSet时动态传入Venue对象。
- 动态设置queryset时,需根据实际模型关系调整:如果
type是外键到独立的Category模型,要修改为关联过滤逻辑。
内容的提问来源于stack exchange,提问作者PhilM
相关产品推荐
相关产品推荐

