This mostly works out of the box, thanks to Django REST Framework. Mostly unique fields, like name or email, are excluded as these will be handled separately.
Signed-off-by: Stephen Finucane <step...@that.guru> --- I need to disable django-filter support when it's not available. However, its use would allow us to get rid of most of 'filters.py'. Is this worth introducing a compulsory dependency for? --- patchwork/api/check.py | 2 ++ patchwork/api/cover.py | 2 ++ patchwork/api/patch.py | 2 ++ patchwork/api/series.py | 3 ++- patchwork/filters.py | 41 +++++++++++++++++++++++++++++++++++++++++ patchwork/settings/base.py | 6 +++++- requirements-test.txt | 2 +- 7 files changed, 55 insertions(+), 3 deletions(-) diff --git a/patchwork/api/check.py b/patchwork/api/check.py index 43463fe..2f0d5fd 100644 --- a/patchwork/api/check.py +++ b/patchwork/api/check.py @@ -27,6 +27,7 @@ from rest_framework.serializers import HyperlinkedModelSerializer from rest_framework.serializers import HyperlinkedIdentityField from patchwork.api import MultipleFieldLookupMixin +from patchwork.filters import CheckFilter from patchwork.models import Check from patchwork.models import Patch @@ -89,6 +90,7 @@ class CheckMixin(object): queryset = Check.objects.prefetch_related('patch', 'user') serializer_class = CheckSerializer + filter_class = CheckFilter class CheckListCreate(CheckMixin, ListCreateAPIView): diff --git a/patchwork/api/cover.py b/patchwork/api/cover.py index 2674be3..189e2ed 100644 --- a/patchwork/api/cover.py +++ b/patchwork/api/cover.py @@ -25,6 +25,7 @@ from rest_framework.serializers import HyperlinkedModelSerializer from rest_framework.serializers import HyperlinkedRelatedField from rest_framework.serializers import SerializerMethodField +from patchwork.filters import CoverLetterFilter from patchwork.models import CoverLetter @@ -67,6 +68,7 @@ class CoverLetterList(ListAPIView): queryset = CoverLetter.objects.all().prefetch_related( 'series').select_related('submitter').defer('content', 'headers') serializer_class = CoverLetterListSerializer + filter_class = CoverLetterFilter class CoverLetterDetail(RetrieveAPIView): diff --git a/patchwork/api/patch.py b/patchwork/api/patch.py index 8d308e8..149b3ae 100644 --- a/patchwork/api/patch.py +++ b/patchwork/api/patch.py @@ -29,6 +29,7 @@ from rest_framework.serializers import SerializerMethodField from patchwork.api import PatchworkPermission from patchwork.api import STATE_CHOICES +from patchwork.filters import PatchFilter from patchwork.models import Patch from patchwork.models import State @@ -118,6 +119,7 @@ class PatchList(ListAPIView): 'content', 'diff', 'headers') permission_classes = (PatchworkPermission,) serializer_class = PatchListSerializer + filter_class = PatchFilter class PatchDetail(RetrieveUpdateAPIView): diff --git a/patchwork/api/series.py b/patchwork/api/series.py index fead4ca..9771bf4 100644 --- a/patchwork/api/series.py +++ b/patchwork/api/series.py @@ -22,6 +22,7 @@ from rest_framework.generics import RetrieveAPIView from rest_framework.serializers import HyperlinkedModelSerializer from patchwork.api import PatchworkPermission +from patchwork.filters import SeriesFilter from patchwork.models import Series @@ -51,7 +52,7 @@ class SeriesMixin(object): class SeriesList(SeriesMixin, ListAPIView): """List series.""" - pass + filter_class = SeriesFilter class SeriesDetail(SeriesMixin, RetrieveAPIView): diff --git a/patchwork/filters.py b/patchwork/filters.py index bc8ca41..5eb833f 100644 --- a/patchwork/filters.py +++ b/patchwork/filters.py @@ -24,7 +24,13 @@ from django.utils.html import escape from django.utils.safestring import mark_safe from django.utils import six from django.utils.six.moves.urllib.parse import quote +from django_filters import CharFilter +from django_filters import FilterSet +from django_filters import IsoDateTimeFilter +from patchwork.models import Check +from patchwork.models import CoverLetter +from patchwork.models import Patch from patchwork.models import Person from patchwork.models import Series from patchwork.models import State @@ -505,3 +511,38 @@ class Filters: if isinstance(f, filterclass): f.set_status(*args, **kwargs) return + + +class TimestampMixin(object): + + # TODO(stephenfin): These should filter on a 'updated_at' field instead + before = IsoDateTimeFilter(name='date', lookup_expr='lt') + since = IsoDateTimeFilter(name='date', lookup_expr='gte') + + +class SeriesFilter(TimestampMixin, FilterSet): + + class Meta: + model = Series + fields = ['submitter'] + + +class CoverLetterFilter(TimestampMixin, FilterSet): + + class Meta: + model = CoverLetter + fields = ['series', 'submitter'] + + +class PatchFilter(FilterSet): + + class Meta: + model = Patch + fields = ['series', 'submitter', 'delegate', 'state', 'archived'] + + +class CheckFilter(TimestampMixin, FilterSet): + + class Meta: + model = Check + fields = ['user', 'state', 'context'] diff --git a/patchwork/settings/base.py b/patchwork/settings/base.py index 35ac96a..dd2d3d0 100644 --- a/patchwork/settings/base.py +++ b/patchwork/settings/base.py @@ -133,7 +133,8 @@ try: import rest_framework # NOQA INSTALLED_APPS += [ - 'rest_framework' + 'rest_framework', + 'django_filters', ] except ImportError: pass @@ -144,6 +145,9 @@ REST_FRAMEWORK = { 'rest_framework.versioning.NamespaceVersioning' ), 'DEFAULT_PAGINATION_CLASS': 'patchwork.api.LinkHeaderPagination', + 'DEFAULT_FILTER_BACKENDS': ( + 'django_filters.rest_framework.DjangoFilterBackend', + ) } # diff --git a/requirements-test.txt b/requirements-test.txt index 7cb5ae9..c664976 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -3,4 +3,4 @@ django-debug-toolbar==1.5 python-dateutil>2.0,<3.0 selenium>2.0,<3.0 djangorestframework>=3.4,<3.5 -drf-nested-routers>=0.11.1,<0.12 +django-filter>=0.15,<0.16 -- 2.7.4 _______________________________________________ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork