The API now supports filtering docs by tag & correspondent, as well as ordering

This commit is contained in:
Daniel Quinn 2016-03-12 20:45:13 +00:00
parent f764f5cb7b
commit 8c5cb163a1
3 changed files with 112 additions and 49 deletions

View File

@ -5,7 +5,7 @@ The REST API
Paperless makes use of the `Django REST Framework`_ standard API interface Paperless makes use of the `Django REST Framework`_ standard API interface
because of its inherent awesomeness. Conveniently, the system is also because of its inherent awesomeness. Conveniently, the system is also
self-documenting, so learn more about the access points, schema, what's self-documenting, so to learn more about the access points, schema, what's
accepted and what isn't, you need only visit ``/api`` on your local Paperless accepted and what isn't, you need only visit ``/api`` on your local Paperless
installation. installation.

View File

@ -4,45 +4,31 @@ from rest_framework import filters
from .models import Document, Correspondent, Tag from .models import Document, Correspondent, Tag
#
class DocumentFilter(filters.FilterSet): # I hate how copy/pastey this file is. Recommendations are welcome.
#
title__startswith = django_filters.CharFilter(
name="title", lookup_type="startswith",
label="Title starts with (case sensitive)"
)
title__istartswith = django_filters.CharFilter(
name="title", lookup_type="istartswith",
label="Title starts with (case insensitive)"
)
title__endswith = django_filters.CharFilter(
name="title", lookup_type="endswith",
label="Title ends with (case sensitive)"
)
title__iendswith = django_filters.CharFilter(
name="title", lookup_type="endswith",
label="Title ends with (case insensitive)"
)
title__contains = django_filters.CharFilter(
name="title", lookup_type="contains",
label="Title contains (case sensitive)"
)
title__icontains = django_filters.CharFilter(
name="title", lookup_type="icontains",
label="Title contains (case insensitive)"
)
content__contains = django_filters.CharFilter(
name="content", lookup_type="contains")
content__icontains = django_filters.CharFilter(
name="content", lookup_type="icontains")
class Meta(object):
model = Document
fields = ["title"]
class SluggableFilter(filters.FilterSet): # Filters
class RelatedFilter(django_filters.MethodFilter):
def __init__(self, *args, **kwargs):
self.key = kwargs.pop("key")
self.lookup_type = kwargs.get("lookup_type")
django_filters.MethodFilter.__init__(self, *args, **kwargs)
def filter(self, qs, value):
if not value:
return qs
return qs.filter(**{"tags__{}".format(self.key): value})
# FilterSets
class SluggableFilterSet(filters.FilterSet):
name__startswith = django_filters.CharFilter( name__startswith = django_filters.CharFilter(
name="name", lookup_type="startswith", name="name", lookup_type="startswith",
@ -83,15 +69,84 @@ class SluggableFilter(filters.FilterSet):
) )
class CorrespondentFilter(SluggableFilter): class CorrespondentFilterSet(SluggableFilterSet):
class Meta(object): class Meta(object):
model = Correspondent model = Correspondent
fields = ["name"] fields = ["name"]
class TagFilter(SluggableFilter): class TagFilterSet(SluggableFilterSet):
class Meta(object): class Meta(object):
model = Tag model = Tag
fields = ["name"] fields = ["name", "slug"]
class DocumentFilterSet(filters.FilterSet):
title__startswith = django_filters.CharFilter(
name="title", lookup_type="startswith",
label="Title starts with (case sensitive)"
)
title__istartswith = django_filters.CharFilter(
name="title", lookup_type="istartswith",
label="Title starts with (case insensitive)"
)
title__endswith = django_filters.CharFilter(
name="title", lookup_type="endswith",
label="Title ends with (case sensitive)"
)
title__iendswith = django_filters.CharFilter(
name="title", lookup_type="endswith",
label="Title ends with (case insensitive)"
)
title__contains = django_filters.CharFilter(
name="title", lookup_type="contains",
label="Title contains (case sensitive)"
)
title__icontains = django_filters.CharFilter(
name="title", lookup_type="icontains",
label="Title contains (case insensitive)"
)
content__contains = django_filters.CharFilter(
name="content", lookup_type="contains")
content__icontains = django_filters.CharFilter(
name="content", lookup_type="icontains")
tags__name = RelatedFilter(key="name")
tags__name__startswith = RelatedFilter(key="name__startswith")
tags__name__istartswith = RelatedFilter(key="name__istartswith")
tags__name__endswith = RelatedFilter(key="name__endswith")
tags__name__iendswith = RelatedFilter(key="name__iendswith")
tags__name__contains = RelatedFilter(key="name__contains")
tags__name__icontains = RelatedFilter(key="name__icontains")
tags__slug = RelatedFilter(key="slug")
tags__slug__startswith = RelatedFilter(key="slug__startswith")
tags__slug__istartswith = RelatedFilter(key="slug__istartswith")
tags__slug__endswith = RelatedFilter(key="slug__endswith")
tags__slug__iendswith = RelatedFilter(key="slug__iendswith")
tags__slug__contains = RelatedFilter(key="slug__contains")
tags__slug__icontains = RelatedFilter(key="slug__icontains")
correspondent__name = RelatedFilter(key="name")
correspondent__name__startswith = RelatedFilter(key="name__startswith")
correspondent__name__istartswith = RelatedFilter(key="name__istartswith")
correspondent__name__endswith = RelatedFilter(key="name__endswith")
correspondent__name__iendswith = RelatedFilter(key="name__iendswith")
correspondent__name__contains = RelatedFilter(key="name__contains")
correspondent__name__icontains = RelatedFilter(key="name__icontains")
correspondent__slug = RelatedFilter(key="slug")
correspondent__slug__startswith = RelatedFilter(key="slug__startswith")
correspondent__slug__istartswith = RelatedFilter(key="slug__istartswith")
correspondent__slug__endswith = RelatedFilter(key="slug__endswith")
correspondent__slug__iendswith = RelatedFilter(key="slug__iendswith")
correspondent__slug__contains = RelatedFilter(key="slug__contains")
correspondent__slug__icontains = RelatedFilter(key="slug__icontains")
class Meta(object):
model = Document
fields = ["title"]

View File

@ -13,7 +13,7 @@ from rest_framework.viewsets import (
from paperless.db import GnuPG from paperless.db import GnuPG
from .filters import DocumentFilter, CorrespondentFilter, TagFilter from .filters import DocumentFilterSet, CorrespondentFilterSet, TagFilterSet
from .forms import UploadForm from .forms import UploadForm
from .models import Correspondent, Tag, Document, Log from .models import Correspondent, Tag, Document, Log
from .serialisers import ( from .serialisers import (
@ -94,8 +94,9 @@ class CorrespondentViewSet(ModelViewSet):
serializer_class = CorrespondentSerializer serializer_class = CorrespondentSerializer
pagination_class = StandardPagination pagination_class = StandardPagination
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
filter_backends = (filters.DjangoFilterBackend,) filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)
filter_class = CorrespondentFilter filter_class = CorrespondentFilterSet
ordering_fields = ("name", "slug")
class TagViewSet(ModelViewSet): class TagViewSet(ModelViewSet):
@ -104,8 +105,9 @@ class TagViewSet(ModelViewSet):
serializer_class = TagSerializer serializer_class = TagSerializer
pagination_class = StandardPagination pagination_class = StandardPagination
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
filter_backends = (filters.DjangoFilterBackend,) filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)
filter_class = TagFilter filter_class = TagFilterSet
ordering_fields = ("name", "slug")
class DocumentViewSet(RetrieveModelMixin, class DocumentViewSet(RetrieveModelMixin,
@ -118,9 +120,14 @@ class DocumentViewSet(RetrieveModelMixin,
serializer_class = DocumentSerializer serializer_class = DocumentSerializer
pagination_class = StandardPagination pagination_class = StandardPagination
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
filter_backends = (filters.DjangoFilterBackend, filters.SearchFilter) filter_backends = (
filter_class = DocumentFilter filters.DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter
)
filter_class = DocumentFilterSet
search_fields = ("title", "correspondent__name", "content") search_fields = ("title", "correspondent__name", "content")
ordering_fields = ("id", "title", "correspondent__name")
class LogViewSet(ReadOnlyModelViewSet): class LogViewSet(ReadOnlyModelViewSet):
@ -129,4 +136,5 @@ class LogViewSet(ReadOnlyModelViewSet):
serializer_class = LogSerializer serializer_class = LogSerializer
pagination_class = StandardPagination pagination_class = StandardPagination
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
filter_backends = (filters.DjangoFilterBackend,) filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)
ordering_fields = ("time",)