如何在生成URL时省略django-filter的空参数?
解决django-filters生成URL时保留空字段的问题
当前使用django-filters过滤查询集时,生成的URL会包含所有空字段参数,例如:
/?price=&producer=&price__gte=4&price__lte=&producer__name=&category__name=&o=-price
希望生成仅包含非空过滤条件的简洁URL:
/?price__gte=4&o=-price
解决方案
方法一:在FilterSet中重写get_form方法(全局生效)
在filters.py的ProductFilter类中添加逻辑,自动过滤空值参数,所有使用该FilterSet的视图都会生效:
class ProductFilter(django_filters.FilterSet): price__gte = django_filters.NumberFilter(field_name="price", lookup_expr="gte") price__lte = django_filters.NumberFilter(field_name="price", lookup_expr="lte") vendor__name = django_filters.CharFilter(lookup_expr="icontains") category__name = django_filters.CharFilter(lookup_expr="icontains") o = django_filters.OrderingFilter( fields=(('price', 'price'),), ) class Meta: model = Product fields = ["price", "category", "vendor"] # 新增:过滤空参数 def get_form(self, *args, **kwargs): form = super().get_form(*args, **kwargs) # 仅保留非空值的参数 cleaned_data = {k: v for k, v in form.data.items() if v} form.data = cleaned_data return form
方法二:在视图中预处理GET参数(仅当前视图生效)
如果只需要在特定视图中实现该效果,可在views.py的get_context_data方法中先过滤空参数,再传入FilterSet:
class ProductListView(LoginRequiredMixin, ListView): model = Product ordering = ["-created_at"] def get_ordering(self): ordering = self.request.GET.get("ordering", "-created_at") return ordering def get_queryset(self, **kwargs): qs = Product.objects.exclude(status="HID").all() return qs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 过滤掉空值的GET参数 filtered_get_params = {k: v for k, v in self.request.GET.items() if v} f = ProductFilter(filtered_get_params, queryset=self.get_queryset()) context["filter"] = f return context
效果说明
两种方法都会自动移除请求中的空值参数,生成的URL仅保留有实际值的过滤条件(如price__gte=4)和排序参数(如o=-price),达到简洁URL的需求。
内容的提问来源于stack exchange,提问作者kraupn3r
相关产品推荐
相关产品推荐

