I've applied the basic example of django-filters with the following setup: 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'),
template:
{% 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
The empty choices ('','---------')
were added to make sure django-filters will display it during filtering and let that field unspecified. However, for the non-mandatory HighestSchool
field it displays twice when using the model in a create scenario with ModelForm.
I.e. ('','---------')
should not be listed for non-mandatory field. Then the empty_label cannot be selected during filtering...
How can this be solved with having one empty_label listed during the create view and have the possibility to leave both mandatory and non-mandatory fields unspecified during filtering?
You can accomplish this within the __init__
by updating the empty_label
directly on the filter, thus avoiding the need to redefine all options.
class FooFilter(django_filters.FilterSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.filters["some_choice_field"].extra.update(empty_label="All")
class Meta:
model = Foo
fields = [
"some_choice_field",
]