filters.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import django_filters
  2. from django.contrib.auth.models import User
  3. from django.contrib.contenttypes.models import ContentType
  4. from dcim.models import Site
  5. from .models import CF_TYPE_SELECT, CustomField, Graph, ExportTemplate, TopologyMap, UserAction
  6. class CustomFieldFilter(django_filters.Filter):
  7. """
  8. Filter objects by the presence of a CustomFieldValue. The filter's name is used as the CustomField name.
  9. """
  10. def __init__(self, cf_type, *args, **kwargs):
  11. self.cf_type = cf_type
  12. super(CustomFieldFilter, self).__init__(*args, **kwargs)
  13. def filter(self, queryset, value):
  14. # Skip filter on empty value
  15. if not value.strip():
  16. return queryset
  17. # Treat 0 as None for Select fields
  18. try:
  19. if self.cf_type == CF_TYPE_SELECT and int(value) == 0:
  20. return queryset.exclude(
  21. custom_field_values__field__name=self.name,
  22. )
  23. except ValueError:
  24. pass
  25. return queryset.filter(
  26. custom_field_values__field__name=self.name,
  27. custom_field_values__serialized_value=value,
  28. )
  29. class CustomFieldFilterSet(django_filters.FilterSet):
  30. """
  31. Dynamically add a Filter for each CustomField applicable to the parent model.
  32. """
  33. def __init__(self, *args, **kwargs):
  34. super(CustomFieldFilterSet, self).__init__(*args, **kwargs)
  35. obj_type = ContentType.objects.get_for_model(self._meta.model)
  36. custom_fields = CustomField.objects.filter(obj_type=obj_type, is_filterable=True)
  37. for cf in custom_fields:
  38. self.filters['cf_{}'.format(cf.name)] = CustomFieldFilter(name=cf.name, cf_type=cf.type)
  39. class GraphFilter(django_filters.FilterSet):
  40. class Meta:
  41. model = Graph
  42. fields = ['type', 'name']
  43. class ExportTemplateFilter(django_filters.FilterSet):
  44. class Meta:
  45. model = ExportTemplate
  46. fields = ['content_type', 'name']
  47. class TopologyMapFilter(django_filters.FilterSet):
  48. site_id = django_filters.ModelMultipleChoiceFilter(
  49. name='site',
  50. queryset=Site.objects.all(),
  51. label='Site',
  52. )
  53. site = django_filters.ModelMultipleChoiceFilter(
  54. name='site__slug',
  55. queryset=Site.objects.all(),
  56. to_field_name='slug',
  57. label='Site (slug)',
  58. )
  59. class Meta:
  60. model = TopologyMap
  61. fields = ['name', 'slug']
  62. class UserActionFilter(django_filters.FilterSet):
  63. username = django_filters.ModelMultipleChoiceFilter(
  64. name='user__username',
  65. queryset=User.objects.all(),
  66. to_field_name='username',
  67. )
  68. class Meta:
  69. model = UserAction
  70. fields = ['user']