You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于函数的视图中如何返回多个自定义过滤器?

How to Combine Multiple Django FilterSets for Your Product List

Looks like you're trying to use two separate FilterSets together in your view and template, but you're running into issues getting both to show up and work correctly. Let's break down the problem and fix it step by step.

The Issue with Your Current Code

Right now, you're initializing two filters (ProductFilter and MyTagFilter) against the original Product.objects.all() queryset, but you're not:

  1. Chaining the filters together to apply both sets of criteria to your products
  2. Passing both filter forms to your template so they render on the page

The cleanest approach is to create a single FilterSet that includes both your title filter and tag filter logic. This avoids having to manage multiple filters in your view and template.

Update your filters.py with a combined filter:

class CombinedProductFilter(django_filters.FilterSet):
    # Include your custom TagFilter here
    tags = TagFilter(field_name='tags__name')
    
    class Meta:
        model = Product
        # Include both fields you want to filter on
        fields = ['title', 'tags']

Then simplify your view to use this single filter:

def product_list(request):
    # Start with all products
    queryset = Product.objects.all()
    # Initialize the combined filter with request parameters
    product_filter = CombinedProductFilter(request.GET, queryset=queryset)
    
    # Pass the filter and filtered products to the template
    return render(request, 'cart/product-list.html', {
        'filter': product_filter,
        'products': product_filter.qs
    })

Your template can stay almost the same (just make sure you're displaying the filtered products):

<div class="row">
    <div class="col-sm-12">
        <form method="get">
            {{ filter.form|crispy }}
            <button class="btn btn-sm amphibian-button-primary btn-block element-shadow img-audio">Submit</button>
        </form>
    </div>
</div>

<!-- Display the filtered products -->
<div class="row mt-4">
    {% for product in products %}
        <div class="col-md-4 mb-3">
            <h5>{{ product.title }}</h5>
            <!-- Add other product details here -->
        </div>
    {% empty %}
        <p>No products match your filters.</p>
    {% endfor %}
</div>

Solution 2: Keep Separate FilterSets and Combine Them in the View

If you need to keep the filters separate for some reason, you can chain them and combine their forms in the view:

Update your view to chain the filters and merge their forms:

from django import forms

def product_list(request):
    queryset = Product.objects.all()
    
    # Apply the first filter, then pass its result to the second filter
    product_filter = ProductFilter(request.GET, queryset=queryset)
    tag_filter = MyTagFilter(request.GET, queryset=product_filter.qs)
    
    # Create a combined form by merging fields from both filters
    combined_form = forms.Form()
    combined_form.fields.update(product_filter.form.fields)
    combined_form.fields.update(tag_filter.form.fields)
    
    return render(request, 'cart/product-list.html', {
        'combined_form': combined_form,
        'products': tag_filter.qs
    })

Then update your template to use combined_form:

<div class="row">
    <div class="col-sm-12">
        <form method="get">
            {{ combined_form|crispy }}
            <button class="btn btn-sm amphibian-button-primary btn-block element-shadow img-audio">Submit</button>
        </form>
    </div>
</div>

<!-- Display filtered products -->
<div class="row mt-4">
    {% for product in products %}
        <div class="col-md-4 mb-3">
            <h5>{{ product.title }}</h5>
            <!-- Other product details -->
        </div>
    {% empty %}
        <p>No products found.</p>
    {% endfor %}
</div>

Key Notes

  • When chaining filters, make sure to pass the filtered queryset (product_filter.qs) to the next filter, not the original queryset. This ensures both filters are applied.
  • If you use the combined Form approach, you might want to adjust the order of fields in the template. You can do this by manually rendering each field instead of using |crispy, or by defining the order in a custom form.

内容的提问来源于stack exchange,提问作者Fabian H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:02:27