asimkon
asimkon

Reputation: 943

django-filter change default form appearance

I have used the library django-filter and it supports its own filter form by default. I use {{filter.form}} in template to print it out. Is there a way to configure and customize it in my own needs so that i do not take the word "Φίλτρο" but something else?

enter image description here

Upvotes: 3

Views: 5078

Answers (2)

Ulugov
Ulugov

Reputation: 347

I faced this issue also, my solution was the following:

filters.py:

from django import forms
from django.utils.translation import ugettext as _
from django.forms.utils import flatatt
from django.contrib.auth.models import User
from .models import Zone, Location, Note, Price, Item, Unit, Category
import django_filters

class PriceFilter(django_filters.FilterSet):
    STATUS_CHOICES = (
        (0, _('Pending')),
        (1, _('Approved')),
        (2, _('Deleted')),
    )

    location = django_filters.ModelChoiceFilter(queryset=Location.objects.all(), widget=forms.Select(attrs={'class': 'form-control form-control-sm'}))
    item = django_filters.ModelChoiceFilter(queryset=Item.objects.all(), widget=forms.Select(attrs={'class': 'form-control form-control-sm'}))
    user = django_filters.ModelChoiceFilter(queryset=User.objects.all(), widget=forms.Select(attrs={'class': 'form-control form-control-sm'}))
    status = django_filters.ChoiceFilter(choices=STATUS_CHOICES, widget=forms.Select(attrs={'class': 'form-control form-control-sm'}))
    date = django_filters.DateFromToRangeFilter(widget=django_filters.widgets.RangeWidget(attrs={'class': 'datepicker form-control form-control-sm', 'placeholder': 'YYYY-MM-DD'}))
    class Meta:
        model = Price
        fields = ('location', 'item', 'unit', 'date', 'status', 'user', 'approved', )

views.py:

from django.shortcuts import get_object_or_404, render, redirect
from django.urls import reverse
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.views import generic, View
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Count
from .models import Zone, Location, Note, Price, Item, Unit, Category
from .forms import NoteForm
from .filters import PriceFilter
...
class IndexView(generic.ListView):
    template_name = 'price/index.html'

    def get(self, request):
        price_list = Price.objects.all().order_by('-date').annotate(num_notes=Count('note'))
        price_filter = PriceFilter(request.GET, queryset=price_list)
        paginator = Paginator(price_filter.qs, 30)
        page = request.GET.get('page')
        try:
            prices = paginator.page(page)
        except PageNotAnInteger:
            prices = paginator.page(1)
        except EmptyPage:
            prices = paginator.page(paginator.num_pages)

        index = paginator.page_range.index(prices.number)
        max_index = len(paginator.page_range)
        start_index = index - 5 if index >= 5 else 0
        end_index = index + 5 if index <= max_index - 5 else max_index
        page_range = paginator.page_range[start_index:end_index]

        return render(request, self.template_name, {
            'prices': prices,
            'filter': price_filter.form,
            'page_range': page_range,
        })

index.html:

{% extends "base/base.html" %}
{% load i18n %}
{% load mptt_tags %}
{% block content %}

<div class="card border-light mb-3">
  <div class="card-header">{% trans 'Filter' %}</div>
  <div class="card-body">
    <form method="get">
    <div class="form-row">
      <div class="form-group col-md-2">
        <label for="inputEmail4" class="col-form-label">{% trans 'Item' %}</label>
        {{ filter.item }}
      </div>
      <div class="form-group col-md-2">
        <label for="inputEmail4" class="col-form-label">{% trans 'Location' %}</label>
        {{ filter.location }}
      </div>
      <div class="form-group col-md-2">
        <label for="inputEmail4" class="col-form-label">{% trans 'Author' %}</label>
        {{ filter.user }}
      </div>
      <div class="form-group col-md-3">
        <label for="inputEmail4" class="col-form-label">{% trans 'Date' %}</label>
        <div class="input-group mb-3 mb-sm-0">
        {{ filter.date }}
        </div>
      </div>
      <div class="form-group col-md-2">
        <label for="inputEmail4" class="col-form-label">{% trans 'Status' %}</label>
        {{ filter.status }}
      </div>
      <div class="form-group col-md-1">
        <label for="inputEmail4" class="col-form-label">{% trans 'Actions' %}</label>
        <button type="submit" class="btn btn-sm btn-primary">{% trans 'Filter' %}</button>
      </div>
    </div>
    </form>
  </div>
</div>

You can use filter like Django's forms but it has some specific widgets also. I advice you to check the documentations: https://django-filter.readthedocs.io/en/develop/ref/filters.html#widget

Upvotes: 5

Serafeim
Serafeim

Reputation: 15104

This word (which is Filter in english) can be configured by using the help_text attribute to your model attributes. I propose to only post the enligsh translations is stackoverflow so that non-greek people will be able to answer.

As an alternative, you may use the FILTERS_HELP_TEXT_FILTER=False setting (http://django-filter.readthedocs.org/en/latest/ref/settings.html) to disable this text (Filter) completely.

Upvotes: 0

Related Questions