将一些参数添加到FilterSet(django-filter)+一些参数

问题描述 投票:2回答:2

我有3个型号:

class Category(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=70, null=True, blank=True)

class SubCategory(models.Model):
    category= models.ForeignKey(Category, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, )

class Products(models.Model):
    user= models.ForeignKey(User, on_delete=models.CASCADE)
    category= models.ForeignKey(Category, on_delete=models.CASCADE)
    subcategory = models.CharField(max_length=200, null=True, blank=True)

并且我有一个接收requestcategory.slug的视图

def category_list(request, slug):
    category = Category.objects.get(slug=slug)
    products = ProductFilter(request.GET, queryset=Products.objects.filter(category=category)

    return render(request, 'products/category_list.html', {"products":products, 'category': category})

[渲染时我收到过滤为QuerySetCategory

我想将category.id发送到ProductsFilter并从数据库中获取动态选项

class ProductsFilter(django_filters.FilterSet):
    subcategory= django_filters.ChoiceFilter(lookup_expr='iexact', choices=TEST, required=False)       

    class Meta:
        model = Products
        fields = {
            "subcategory",
        }

想要将choices=TEST更改为choices=list(SubCategory.objects.filter(category_id=category.id)

这可能吗?

django django-forms django-filter django-filters
2个回答
1
投票

您可以在FilterSet.__init__方法中进行处理。如下所示(请注意,我还没有测试过,可能需要一些摆弄):

class ProductsFilter(django_filters.FilterSet):
    subcategory= django_filters.ChoiceFilter(lookup_expr='iexact', choices=[], required=False)

    def __init__(self, category, *args, **kwargs):
        super(ProductsFilter, self).__init__(*args, **kwargs)

        choices = self.fields['subcategory'].extra['choices']
        choices += [
            (subcat.name, subcat.name) for subcat 
            in SubCategory.objects.filter(category=category)
        ]

    class Meta:
        model = Products

0
投票

@ Sherpa的回答只有两个小问题。首先,应将fields替换为filters。其次,您不能使用+=运算符,必​​须直接分配给过滤器的extra。这是我两种不同方式的工作代码

class LayoutFilterView(filters.FilterSet):
    supplier = filters.ChoiceFilter(
        label=_('Supplier'), empty_label=_("All Suppliers"),)

    def __init__(self, *args, **kwargs):
        super(LayoutFilterView, self).__init__(*args, **kwargs)

        # First Method
        self.filters['supplier'].extra['choices'] = [
            (supplier.id, supplier.name) for supplier in ourSuppliers(request=self.request)
        ]

        # Second Method
        self.filters['supplier'].extra.update({
            'choices': [(supplier.id, supplier.name) for supplier in ourSuppliers(request=self.request)]
        })

原始发布的here

© www.soinside.com 2019 - 2024. All rights reserved.