Django 使用 FilterSet 过滤布尔值
Django using FilterSet for filtering on boolean values
在我的网站上,我有一个页面显示所有产品的列表,这些产品的搜索引擎是用 FilterSet 构建的。一切正常,但我想再添加一个搜索选项。我希望能够过滤所有属性设置为 True 的产品,但是当未标记复选框时我想显示所有产品。使用复选框,过滤工作正常,但就像我说的那样,我想在未标记该框时显示所有产品。我知道使用复选框是一种不好的方法,因为当未标记复选框时,它认为该值为 False。所以我尝试使用 RadioSelect 但没有任何效果,在我的过滤器选项卡中我只有 radioselect 的标题和下面的白色矩形但我不能在上面写或做任何事情。那么我必须使用什么?
这是我的代码。我要显示的产品来自模型 Plat
,属性是来自模型 Chef
的属性 is_delivering
,它链接到 Plat
,在 Plat
.
models.py
class Chef(models.Model):
is_delivering = models.BooleanField(verbose_name = "Livraison ?", default = False)
class Plat(models.Model):
titre = models.CharField(max_length = 100)
description = models.TextField(null = True)
allergenes = models.TextField(null = True)
prix = models.IntegerField(verbose_name = "Prix par portion")
chef = models.ForeignKey('inscription.Chef', on_delete = models.CASCADE)
date_prep = models.DateTimeField(default=timezone.now, verbose_name="Date et heure de préparation")
nb_portions = models.IntegerField(verbose_name = "Nombre de portions disponibles")
photo = models.ImageField(upload_to = "photos_plat/")
is_ordered = models.BooleanField(default=False)
filters.py
class PlatFilter(django_filters.FilterSet):
titre = django_filters.CharFilter(
field_name='titre', label='Mot clé :', lookup_expr='icontains',
widget=forms.TextInput(attrs={'class': 'form-control'}),
)
prix_min = django_filters.NumberFilter(
field_name='prix', label='Prix minimum :', lookup_expr='gte',
widget=forms.NumberInput(attrs={'class': 'form-control'}),
)
prix_max = django_filters.NumberFilter(
field_name='prix', label='Prix maximum :', lookup_expr='lte',
widget=forms.NumberInput(attrs={'class': 'form-control'}),
)
nb_portions = django_filters.NumberFilter(
field_name='nb_portions', label='Nombre de portions minimum :', lookup_expr='gte',
widget=forms.NumberInput(attrs={'class': 'form-control'}),
)
date_prep = django_filters.DateFilter(
field_name='date_prep__date', label='Date de préparation (format JJ/MM/AAAA)', lookup_expr='exact',
widget=forms.DateTimeInput(attrs={'class': 'form-control'}),
)
CHOICES = (('Oui', True), ('Non', False))
is_delivering = django_filters.BooleanFilter(
field_name='chef__is_delivering', label='Livraison comprise',
widget=forms.RadioSelect(attrs={'class': 'form-control', 'choices': CHOICES}),
)
class Meta:
model = Plat
fields = ['titre', 'nb_portions', 'date_prep']
提前致谢!
编辑(渲染问题):
base.html
<div class="filters-body">
<form method="get">
<div class="well">
<div class="row">
<div class="col-md-12 pl-5 pb-4 pt-4 pr-5">
{% csrf_token %}
{% for field in filter.form %}
<div class="fieldWrapper form-group" style="font-size: 150%">
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-search"></span> Rechercher
</button>
</div>
</div>
</div>
</form>
</div>
图片渲染问题:
这里有两个问题:
- 选择由二元组组成,但第一个项是值,第二个是标签;和
choices
不是RadioSelect
的attr
,而是一个参数。
您可以通过以下方式解决此问题:
CHOICES = ((<b>True,</b> 'Oui'), (<b>False,</b> 'Non'))
is_delivering = django_filters.BooleanFilter(
field_name='chef__is_delivering', label='Livraison comprise',
widget=forms.RadioSelect(attrs={'class': 'form-control'}, <b>choices=CHOICES</b>),
)
在我的网站上,我有一个页面显示所有产品的列表,这些产品的搜索引擎是用 FilterSet 构建的。一切正常,但我想再添加一个搜索选项。我希望能够过滤所有属性设置为 True 的产品,但是当未标记复选框时我想显示所有产品。使用复选框,过滤工作正常,但就像我说的那样,我想在未标记该框时显示所有产品。我知道使用复选框是一种不好的方法,因为当未标记复选框时,它认为该值为 False。所以我尝试使用 RadioSelect 但没有任何效果,在我的过滤器选项卡中我只有 radioselect 的标题和下面的白色矩形但我不能在上面写或做任何事情。那么我必须使用什么?
这是我的代码。我要显示的产品来自模型 Plat
,属性是来自模型 Chef
的属性 is_delivering
,它链接到 Plat
,在 Plat
.
models.py
class Chef(models.Model):
is_delivering = models.BooleanField(verbose_name = "Livraison ?", default = False)
class Plat(models.Model):
titre = models.CharField(max_length = 100)
description = models.TextField(null = True)
allergenes = models.TextField(null = True)
prix = models.IntegerField(verbose_name = "Prix par portion")
chef = models.ForeignKey('inscription.Chef', on_delete = models.CASCADE)
date_prep = models.DateTimeField(default=timezone.now, verbose_name="Date et heure de préparation")
nb_portions = models.IntegerField(verbose_name = "Nombre de portions disponibles")
photo = models.ImageField(upload_to = "photos_plat/")
is_ordered = models.BooleanField(default=False)
filters.py
class PlatFilter(django_filters.FilterSet):
titre = django_filters.CharFilter(
field_name='titre', label='Mot clé :', lookup_expr='icontains',
widget=forms.TextInput(attrs={'class': 'form-control'}),
)
prix_min = django_filters.NumberFilter(
field_name='prix', label='Prix minimum :', lookup_expr='gte',
widget=forms.NumberInput(attrs={'class': 'form-control'}),
)
prix_max = django_filters.NumberFilter(
field_name='prix', label='Prix maximum :', lookup_expr='lte',
widget=forms.NumberInput(attrs={'class': 'form-control'}),
)
nb_portions = django_filters.NumberFilter(
field_name='nb_portions', label='Nombre de portions minimum :', lookup_expr='gte',
widget=forms.NumberInput(attrs={'class': 'form-control'}),
)
date_prep = django_filters.DateFilter(
field_name='date_prep__date', label='Date de préparation (format JJ/MM/AAAA)', lookup_expr='exact',
widget=forms.DateTimeInput(attrs={'class': 'form-control'}),
)
CHOICES = (('Oui', True), ('Non', False))
is_delivering = django_filters.BooleanFilter(
field_name='chef__is_delivering', label='Livraison comprise',
widget=forms.RadioSelect(attrs={'class': 'form-control', 'choices': CHOICES}),
)
class Meta:
model = Plat
fields = ['titre', 'nb_portions', 'date_prep']
提前致谢!
编辑(渲染问题):
base.html
<div class="filters-body">
<form method="get">
<div class="well">
<div class="row">
<div class="col-md-12 pl-5 pb-4 pt-4 pr-5">
{% csrf_token %}
{% for field in filter.form %}
<div class="fieldWrapper form-group" style="font-size: 150%">
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-search"></span> Rechercher
</button>
</div>
</div>
</div>
</form>
</div>
图片渲染问题:
这里有两个问题:
- 选择由二元组组成,但第一个项是值,第二个是标签;和
choices
不是RadioSelect
的attr
,而是一个参数。
您可以通过以下方式解决此问题:
CHOICES = ((<b>True,</b> 'Oui'), (<b>False,</b> 'Non'))
is_delivering = django_filters.BooleanFilter(
field_name='chef__is_delivering', label='Livraison comprise',
widget=forms.RadioSelect(attrs={'class': 'form-control'}, <b>choices=CHOICES</b>),
)