1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Added 'none' options to filters for optional fields

This commit is contained in:
Jeremy Stretch
2016-09-15 17:12:53 -04:00
parent daadf7a49b
commit 9dea5656ad
10 changed files with 142 additions and 79 deletions

View File

@@ -0,0 +1,43 @@
import django_filters
from django.db.models import Q
class NullableModelMultipleChoiceFilter(django_filters.MultipleChoiceFilter):
def __init__(self, *args, **kwargs):
# Convert the queryset to a list of choices prefixed with a "None" option
queryset = kwargs.pop('queryset')
self.to_field_name = kwargs.pop('to_field_name', 'pk')
kwargs['choices'] = [(0, 'None')] + [(getattr(o, self.to_field_name), o) for o in queryset]
super(NullableModelMultipleChoiceFilter, self).__init__(*args, **kwargs)
def filter(self, qs, value):
value = value or () # Make sure we have an iterable
if self.is_noop(qs, value):
return qs
# Even though not a noop, no point filtering if empty
if not value:
return qs
q = Q()
for v in set(value):
# Filtering on NULL
if v == str(0):
arg = {'{}__isnull'.format(self.name): True}
# Filtering on a related field (e.g. slug)
elif self.to_field_name != 'pk':
arg = {'{}__{}'.format(self.name, self.to_field_name): v}
# Filtering on primary key
else:
arg = {self.name: v}
if self.conjoined:
qs = self.get_method(qs)(**arg)
else:
q |= Q(**arg)
if self.distinct:
return self.get_method(qs)(q).distinct()
return self.get_method(qs)(q)

View File

@@ -43,7 +43,7 @@ def get_filter_choices(model, id_field='pk', select_related=[], count_field=None
:param id_field: Field to use as the object identifier
:param select_related: Any related tables to include
:param count_field: The field to use for a child COUNT() (optional)
:param null_option: A (value, label) tuple to include at the beginning of the list serving as "null"
:param null_option: A choice to include at the beginning of the list serving as "null"
"""
queryset = model.objects.all()
if select_related:
@@ -54,7 +54,7 @@ def get_filter_choices(model, id_field='pk', select_related=[], count_field=None
else:
choices = [(getattr(obj, id_field), u'{}'.format(obj)) for obj in queryset]
if null_option:
choices = [null_option] + choices
choices = [(0, null_option)] + choices
return choices