public
Created

Custom filter field for django-filter. Control two fields in a flexible manner.

  • Download Gist
filter.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
from django import forms
import django_filters
from django_filters.filters import Filter
 
CHOICES = (('AND', 'AND'), ('OR', 'OR'))
 
class NamePriceWidget(forms.MultiWidget):
def __init__(self, attrs=None):
widgets = (
forms.TextInput(attrs=attrs),
forms.Select(choices=CHOICES),
forms.TextInput(attrs=attrs)
)
super(NamePriceWidget, self).__init__(widgets, attrs)
 
def decompress(self, value):
if value:
return [value.start, value.operator, value.value.stop]
return [None, None, None]
 
def format_output(self, rendered_widgets):
return '-'.join(rendered_widgets)
 
 
class NamePriceField(forms.MultiValueField):
widget = NamePriceWidget
 
def __init__(self, *args, **kwargs):
fields = (
forms.CharField(),
forms.ChoiceField(choices=CHOICES),
forms.DecimalField(),
)
super(NamePriceField, self).__init__(fields, *args, **kwargs)
 
def compress(self, data_list):
if data_list:
return data_list
return None
 
from django.db.models import Q
 
class NamePriceFilter(Filter):
field_class = NamePriceField
 
def filter(self, qs, value):
if value:
q_object = Q()
 
try:
operator = {'AND': Q.AND, 'OR': Q.OR}[value[1]]
except KeyError:
operator = Q.AND
 
if value[0]:
q_object = Q(name__startswith=value[0])
if value[2]:
q_object.add(Q(price__lte=value[2]), operator)
return qs.filter(q_object)
return qs

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.