我使用以下设置应用了django-filters的基本示例: models.py
class Shopper(models.Model):
FirstName = models.CharField(max_length=30)
LastName = models.CharField(max_length=30)
Gender_CHOICES = (
('','---------'),
('Male','Male'),
('Female','Female'),
)
Gender = models.CharField(max_length=6, choices=Gender_CHOICES, default=None)
School_CHOICES = (
('','---------'),
(u'1', 'Primary school'),
(u'2', 'High School'),
(u'3', 'Apprenticeship'),
(u'4', 'BsC'),
(u'5', 'MsC'),
(u'6', 'MBA'),
(u'7', 'PhD'),
)
HighestSchool = models.CharField(max_length=40, blank = True, choices = School_CHOICES,default=None)
views.py:
def shopperlist(request):
f = ShopperFilter(request.GET, queryset=Shopper.objects.all())
return render(request,'mysapp/emailcampaign.html', {'filter': f})
urls.py:
url(r'^emailcampaign/$', views.shopperlist, name='EmailCampaign'),
模板:
{% extends "basewlogout.html" %}
{% block content %}
{% csrf_token %}
<form action="" method="get">
{{ filter.form.as_p }}
<input type="submit" name="Filter" value="Filter" />
</form>
{% for obj in filter %}
<li>{{ obj.FirstName }} {{ obj.LastName }} {{ obj.Email }}</li>
{% endfor %}
<a href="{% url 'UserLogin' %}">
<p> Return to home page. </p> </a>
{% endblock %}
forms.py:
class ShopperForm(ModelForm):
class Meta:
model = Shopper
添加了空选项('','---------')
以确保django-filters在过滤期间显示它并且不指定该字段。但是,对于非强制性HighestSchool
字段,在使用ModelForm.
I.e的创建方案中使用模型时,它会显示两次。不应列出非强制性字段('','---------')
。然后在过滤期间无法选择empty_label ...
如何通过在创建视图中列出一个empty_label来解决这个问题,并且可以在过滤期间保留未指定的强制字段和非强制字段?
答案 0 :(得分:6)
首先,您不应将空白选项添加到您的选择集中。所以请删除以下内容:
('','---------'),
当不需要Field时,Django会自动添加这些内容(django模型,django形式,django视图等)除了 django-filter将按预期工作。
现在,关于django-filter。您所描述的是一个常见的要求,已经出现在django-filter project的问题中。请在此处查看可能的解决方法https://github.com/alex/django-filter/issues/45。我将从那里复制粘贴cvk77的代码以供参考:
class NicerFilterSet(django_filters.FilterSet): def __init__(self, *args, **kwargs): super(NicerFilterSet, self).__init__(*args, **kwargs) for name, field in self.filters.iteritems(): if isinstance(field, ChoiceFilter): # Add "Any" entry to choice fields. field.extra['choices'] = tuple([("", "Any"), ] + list(field.extra['choices']))`
所以使用它只是从NicerFilterSet而不是普通的FilterSet扩展你的过滤器。
您还可以执行以下Q + D解决方案:在models.py中定义全局变量:
GENDER_CHOICES = ( ('Male','Male'), ('Female','Female'), )
并在模型中按预期使用它。
现在,在您的filters.py中定义另一个全局变量:
FILTER_GENDER_CHOICES = list(models.FILTER_CHOICES) FILTER_GENDER_CHOICES.insert(0, ('','---------') )
然后像这样定义你的过滤器:
class ShopperFilter(django_filters.FilterSet): gender = django_filters.ChoiceFilter(choices= FILTER_GENDER_CHOICES ) class Meta: model = models.Shopper
答案 1 :(得分:0)
对于经验较少的人来说,这是cvk77原始解决方案的Python3兼容版本,我在@Serafeim接受的答案中找到了。
class NicerFilterSet(django_filters.FilterSet):
def __init__(self, *args, **kwargs):
super(NicerFilterSet, self).__init__(*args, **kwargs)
for name, field in self.filters.items():
if isinstance(field, ChoiceFilter):
# Add "Any" entry to choice fields.
field.extra['choices'] = tuple([("", "Any"), ] + list(field.extra['choices']))
的变化:
self.filters.iteritems()
已更改为self.filters.items()