mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Update query filters to OR multiple values
This commit is contained in:
@ -1,10 +1,51 @@
|
||||
import django_filters
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from django.db import models
|
||||
|
||||
from extras.models import Tag
|
||||
|
||||
|
||||
def multivalue_field_factory(field_class):
|
||||
"""
|
||||
Given a form field class, return a subclass capable of accepting multiple values. This allows us to OR on multiple
|
||||
filter values while maintaining the field's built-in vlaidation. Example: GET /api/dcim/devices/?name=foo&name=bar
|
||||
"""
|
||||
class NewField(field_class):
|
||||
widget = forms.SelectMultiple
|
||||
|
||||
def to_python(self, value):
|
||||
if not value:
|
||||
return []
|
||||
return [super(field_class, self).to_python(v) for v in value]
|
||||
|
||||
return type('MultiValue{}'.format(field_class.__name__), (NewField,), dict())
|
||||
|
||||
|
||||
#
|
||||
# Filters
|
||||
#
|
||||
|
||||
class MultiValueCharFilter(django_filters.MultipleChoiceFilter):
|
||||
field_class = multivalue_field_factory(forms.CharField)
|
||||
|
||||
|
||||
class MultiValueDateFilter(django_filters.MultipleChoiceFilter):
|
||||
field_class = multivalue_field_factory(forms.DateField)
|
||||
|
||||
|
||||
class MultiValueDateTimeFilter(django_filters.MultipleChoiceFilter):
|
||||
field_class = multivalue_field_factory(forms.DateTimeField)
|
||||
|
||||
|
||||
class MultiValueNumberFilter(django_filters.MultipleChoiceFilter):
|
||||
field_class = multivalue_field_factory(forms.IntegerField)
|
||||
|
||||
|
||||
class MultiValueTimeFilter(django_filters.MultipleChoiceFilter):
|
||||
field_class = multivalue_field_factory(forms.TimeField)
|
||||
|
||||
|
||||
class TreeNodeMultipleChoiceFilter(django_filters.ModelMultipleChoiceFilter):
|
||||
"""
|
||||
Filters for a set of Models, including all descendant models within a Tree. Example: [<Region: R1>,<Region: R2>]
|
||||
@ -48,6 +89,10 @@ class TagFilter(django_filters.ModelMultipleChoiceFilter):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
#
|
||||
# FilterSets
|
||||
#
|
||||
|
||||
class NameSlugSearchFilterSet(django_filters.FilterSet):
|
||||
"""
|
||||
A base class for adding the search method to models which only expose the `name` and `slug` fields
|
||||
@ -61,6 +106,57 @@ class NameSlugSearchFilterSet(django_filters.FilterSet):
|
||||
if not value.strip():
|
||||
return queryset
|
||||
return queryset.filter(
|
||||
Q(name__icontains=value) |
|
||||
Q(slug__icontains=value)
|
||||
models.Q(name__icontains=value) |
|
||||
models.Q(slug__icontains=value)
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Update default filters
|
||||
#
|
||||
|
||||
FILTER_DEFAULTS = django_filters.filterset.FILTER_FOR_DBFIELD_DEFAULTS
|
||||
FILTER_DEFAULTS.update({
|
||||
models.AutoField: {
|
||||
'filter_class': MultiValueNumberFilter
|
||||
},
|
||||
models.CharField: {
|
||||
'filter_class': MultiValueCharFilter
|
||||
},
|
||||
models.DateField: {
|
||||
'filter_class': MultiValueDateFilter
|
||||
},
|
||||
models.DateTimeField: {
|
||||
'filter_class': MultiValueDateTimeFilter
|
||||
},
|
||||
models.DecimalField: {
|
||||
'filter_class': MultiValueNumberFilter
|
||||
},
|
||||
models.EmailField: {
|
||||
'filter_class': MultiValueCharFilter
|
||||
},
|
||||
models.FloatField: {
|
||||
'filter_class': MultiValueNumberFilter
|
||||
},
|
||||
models.IntegerField: {
|
||||
'filter_class': MultiValueNumberFilter
|
||||
},
|
||||
models.PositiveIntegerField: {
|
||||
'filter_class': MultiValueNumberFilter
|
||||
},
|
||||
models.PositiveSmallIntegerField: {
|
||||
'filter_class': MultiValueNumberFilter
|
||||
},
|
||||
models.SlugField: {
|
||||
'filter_class': MultiValueCharFilter
|
||||
},
|
||||
models.SmallIntegerField: {
|
||||
'filter_class': MultiValueNumberFilter
|
||||
},
|
||||
models.TimeField: {
|
||||
'filter_class': MultiValueTimeFilter
|
||||
},
|
||||
models.URLField: {
|
||||
'filter_class': MultiValueCharFilter
|
||||
},
|
||||
})
|
||||
|
Reference in New Issue
Block a user