mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Fixes #164
There appears to be quite the mess out there with regard to how DRF handles filtering. DRF has its own built-in stuff, but recommends django_filter for the advanced stuff, which has its own overriding module that explodes with this message when used as per the documentation: AttributeError: 'NoneType' object has no attribute 'DjangoFilterBackend' Then there's djangorestframework-filter, another package that claims to do the same thing, that does everything just differently enough that nothing worked while I had it enabled. I ended up using django_filter, but doing so importing each element explicitly, rather than just using the recommended (and broken, at least in this project) method of: import django_filter.restframework as fitlers Anyway, this should bring the dependencies up to date, and strips out a lot of redundant code.
This commit is contained in:
parent
9ea39aeecb
commit
294b8abc3f
@ -1,10 +1,9 @@
|
||||
Django==1.10.3
|
||||
Django==1.10.4
|
||||
Pillow>=3.1.1
|
||||
django-crispy-forms>=1.6.0
|
||||
django-extensions>=1.6.1
|
||||
django-filter>=0.12.0,<1.0
|
||||
django-filter>=1.0
|
||||
djangorestframework>=3.4.4
|
||||
djangorestframework-filters>=0.8.0
|
||||
filemagic>=1.6
|
||||
langdetect>=1.0.5
|
||||
pyocr>=0.3.1
|
||||
|
@ -1,152 +1,58 @@
|
||||
import django_filters
|
||||
from django_filters.rest_framework import CharFilter, FilterSet
|
||||
|
||||
from rest_framework import filters
|
||||
|
||||
from .models import Document, Correspondent, Tag
|
||||
|
||||
#
|
||||
# I hate how copy/pastey this file is. Recommendations are welcome.
|
||||
#
|
||||
from .models import Correspondent, Document, Tag
|
||||
|
||||
|
||||
# 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="name", lookup_type="startswith",
|
||||
label="Name starts with (case sensitive)"
|
||||
)
|
||||
name__istartswith = django_filters.CharFilter(
|
||||
name="name", lookup_type="istartswith",
|
||||
label="Name starts with (case insensitive)"
|
||||
)
|
||||
name__endswith = django_filters.CharFilter(
|
||||
name="name", lookup_type="endswith",
|
||||
label="Name ends with (case sensitive)"
|
||||
)
|
||||
name__iendswith = django_filters.CharFilter(
|
||||
name="name", lookup_type="endswith",
|
||||
label="Name ends with (case insensitive)"
|
||||
)
|
||||
name__contains = django_filters.CharFilter(
|
||||
name="name", lookup_type="contains",
|
||||
label="Name contains (case sensitive)"
|
||||
)
|
||||
name__icontains = django_filters.CharFilter(
|
||||
name="name", lookup_type="icontains",
|
||||
label="Name contains (case insensitive)"
|
||||
)
|
||||
|
||||
slug__istartswith = django_filters.CharFilter(
|
||||
name="slug", lookup_type="istartswith",
|
||||
label="Slug starts with (case insensitive)"
|
||||
)
|
||||
slug__iendswith = django_filters.CharFilter(
|
||||
name="slug", lookup_type="endswith",
|
||||
label="Slug ends with (case insensitive)"
|
||||
)
|
||||
slug__icontains = django_filters.CharFilter(
|
||||
name="slug", lookup_type="icontains",
|
||||
label="Slug contains (case insensitive)"
|
||||
)
|
||||
|
||||
|
||||
class CorrespondentFilterSet(SluggableFilterSet):
|
||||
class CorrespondentFilterSet(FilterSet):
|
||||
|
||||
class Meta(object):
|
||||
model = Correspondent
|
||||
fields = ["name"]
|
||||
fields = {
|
||||
'name': [
|
||||
"startswith", "endswith", "contains",
|
||||
"istartswith", "iendswith", "icontains"
|
||||
],
|
||||
"slug": ["istartswith", "iendswith", "icontains"]
|
||||
}
|
||||
|
||||
|
||||
class TagFilterSet(SluggableFilterSet):
|
||||
class TagFilterSet(FilterSet):
|
||||
|
||||
class Meta(object):
|
||||
model = Tag
|
||||
fields = ["name", "slug"]
|
||||
fields = {
|
||||
'name': [
|
||||
"startswith", "endswith", "contains",
|
||||
"istartswith", "iendswith", "icontains"
|
||||
],
|
||||
"slug": ["istartswith", "iendswith", "icontains"]
|
||||
}
|
||||
|
||||
|
||||
class DocumentFilterSet(filters.FilterSet):
|
||||
class DocumentFilterSet(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)"
|
||||
)
|
||||
CHAR_KWARGS = {
|
||||
"lookup_expr": (
|
||||
"startswith",
|
||||
"endswith",
|
||||
"contains",
|
||||
"istartswith",
|
||||
"iendswith",
|
||||
"icontains"
|
||||
)
|
||||
}
|
||||
|
||||
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")
|
||||
correspondent__name = CharFilter(name="correspondent__name", **CHAR_KWARGS)
|
||||
correspondent__slug = CharFilter(name="correspondent__slug", **CHAR_KWARGS)
|
||||
tags__name = CharFilter(name="tags__name", **CHAR_KWARGS)
|
||||
tags__slug = CharFilter(name="tags__slug", **CHAR_KWARGS)
|
||||
|
||||
class Meta(object):
|
||||
model = Document
|
||||
fields = ["title"]
|
||||
fields = {
|
||||
"title": [
|
||||
"startswith", "endswith", "contains",
|
||||
"istartswith", "iendswith", "icontains"
|
||||
],
|
||||
"content": ["contains", "icontains"],
|
||||
}
|
||||
|
@ -1,23 +1,33 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.http import HttpResponse
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic import FormView, DetailView, TemplateView
|
||||
|
||||
from rest_framework import filters
|
||||
from django.views.generic import DetailView, FormView, TemplateView
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from rest_framework.filters import SearchFilter, OrderingFilter
|
||||
from paperless.db import GnuPG
|
||||
from rest_framework.mixins import (
|
||||
RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, ListModelMixin)
|
||||
DestroyModelMixin,
|
||||
ListModelMixin,
|
||||
RetrieveModelMixin,
|
||||
UpdateModelMixin
|
||||
)
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.viewsets import (
|
||||
ModelViewSet, ReadOnlyModelViewSet, GenericViewSet)
|
||||
GenericViewSet,
|
||||
ModelViewSet,
|
||||
ReadOnlyModelViewSet
|
||||
)
|
||||
|
||||
from paperless.db import GnuPG
|
||||
|
||||
from .filters import DocumentFilterSet, CorrespondentFilterSet, TagFilterSet
|
||||
from .filters import CorrespondentFilterSet, DocumentFilterSet, TagFilterSet
|
||||
from .forms import UploadForm
|
||||
from .models import Correspondent, Tag, Document, Log
|
||||
from .models import Correspondent, Document, Log, Tag
|
||||
from .serialisers import (
|
||||
CorrespondentSerializer, TagSerializer, DocumentSerializer, LogSerializer)
|
||||
CorrespondentSerializer,
|
||||
DocumentSerializer,
|
||||
LogSerializer,
|
||||
TagSerializer
|
||||
)
|
||||
|
||||
|
||||
class IndexView(TemplateView):
|
||||
@ -94,7 +104,7 @@ class CorrespondentViewSet(ModelViewSet):
|
||||
serializer_class = CorrespondentSerializer
|
||||
pagination_class = StandardPagination
|
||||
permission_classes = (IsAuthenticated,)
|
||||
filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)
|
||||
filter_backends = (DjangoFilterBackend, OrderingFilter)
|
||||
filter_class = CorrespondentFilterSet
|
||||
ordering_fields = ("name", "slug")
|
||||
|
||||
@ -105,7 +115,7 @@ class TagViewSet(ModelViewSet):
|
||||
serializer_class = TagSerializer
|
||||
pagination_class = StandardPagination
|
||||
permission_classes = (IsAuthenticated,)
|
||||
filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)
|
||||
filter_backends = (DjangoFilterBackend, OrderingFilter)
|
||||
filter_class = TagFilterSet
|
||||
ordering_fields = ("name", "slug")
|
||||
|
||||
@ -120,11 +130,7 @@ class DocumentViewSet(RetrieveModelMixin,
|
||||
serializer_class = DocumentSerializer
|
||||
pagination_class = StandardPagination
|
||||
permission_classes = (IsAuthenticated,)
|
||||
filter_backends = (
|
||||
filters.DjangoFilterBackend,
|
||||
filters.SearchFilter,
|
||||
filters.OrderingFilter
|
||||
)
|
||||
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
|
||||
filter_class = DocumentFilterSet
|
||||
search_fields = ("title", "correspondent__name", "content")
|
||||
ordering_fields = (
|
||||
@ -137,5 +143,5 @@ class LogViewSet(ReadOnlyModelViewSet):
|
||||
serializer_class = LogSerializer
|
||||
pagination_class = StandardPagination
|
||||
permission_classes = (IsAuthenticated,)
|
||||
filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)
|
||||
filter_backends = (DjangoFilterBackend, OrderingFilter)
|
||||
ordering_fields = ("time",)
|
||||
|
@ -36,7 +36,6 @@ if os.path.exists("/etc/paperless.conf"):
|
||||
load_dotenv("/etc/paperless.conf")
|
||||
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
|
Loading…
x
Reference in New Issue
Block a user