FilterSet(django-filter)添加一些参数+一些参数
Add some parameters to FilterSet (django-filter) + some parameters
我有 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)
我有一个视图接收 request
和 category.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})
渲染时我收到 QuerySet
过滤为 Category
我想将 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)
这可能吗?
您可以在 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
@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)]
})
最初发布
我有 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)
我有一个视图接收 request
和 category.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})
渲染时我收到 QuerySet
过滤为 Category
我想将 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)
这可能吗?
您可以在 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
@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)]
})
最初发布