Reputation: 174
Very new here to django/python. I have a web page that makes use of django_filters for filtering a product view by category, and then orders them by price. I am not sure how to actually format the output in the template. Any help is appreciated:
views.py
class HomeView(ListView):
model = Post #indicating which model to use from models.py
template_name = 'home.html' #specify which html file to use as the template
context_object_name = 'all_posts_list' #Default: object_list
ordering = ['price'] #reorder by price
paginate_by = 16
#queryset = Post.objects.all() #Default: Model.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = PostFilter(self.request.GET, queryset=self.get_queryset())
return context
filters.py
class PostFilter(django_filters.FilterSet):
CHOICES = (
('highToLow', 'Highest-to-Lowest'),
('lowToHigh', 'Lowest-to-Highest'),
)
ordering = django_filters.ChoiceFilter(label='Price', choices=CHOICES, method='filter_by_order')
class Meta:
model = Post
fields = ['category']
def filter_by_order(self, queryset, name, value):
expression = 'price' if value == 'highToLow' else '-price'
return queryset.order_by(expression)
html template
{% load bootstrap %}
{% block menubar %}
<form class="form-inline" method="GET" style="color: white; font-weight: bold;">
{{ filter.form|bootstrap }}
<button type="submit" class="btn btn-warning">Go</button>
</form>
{% endblock %}
I am not sure how to actually format the labels and dropdowns being produced by the filter.form, other than adding the bootstrap |, which still does not help with spacing or alignment of labels. Again, super new and any help appreciated, direction to further documentation, reading, etc...
Upvotes: 1
Views: 1741
Reputation: 3337
It's almost same of how you doing Form
customization.
label
will be showed as label for the field, also you can use a customized widget
and pass placeholder, class
to control how the form looks.
from django.forms.widgets import Input
django_filters.CharFilter(label='name_starts', method=filter_name_starts,
widget = Input(attrs={'placeholder':'filter by first letter...', 'class': 'form-control'}))
Internally, Filter
class hold a default form Field
as a class attribute, paramters defined on the Filter
related to form are passed to form Field
to render the HTML.
Then consult to Manually render django form, then you can customize the form looks in field level
ChoiceFilter
is kind of special here, if you would like to change the empty_label of the category, you need add a new line.
CHOICES = (
('', '----'), # replace the value '----' with your values, served just like placeholder in CharField
('highToLow', 'Highest-to-Lowest'),
('lowToHigh', 'Lowest-to-Highest'),
)
if you use class Meta
: you can not override widgets in the definition time, in this case. you can do some adjustments after the filter initialized.note, this also works for other ChoiceFilter
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# change the widget choices after initialization
self.form.fields['category'].widget.choices = [("", "please select a value"),] + list(self.form.fields["category"].choices)[1:]
Upvotes: 1