add backend support for saved views

This commit is contained in:
jonaswinkler 2020-12-12 15:46:56 +01:00
parent bf9051e44d
commit dfa1f29809
6 changed files with 152 additions and 5 deletions

View File

@ -4,7 +4,8 @@ from django.utils.safestring import mark_safe
from whoosh.writing import AsyncWriter
from . import index
from .models import Correspondent, Document, DocumentType, Log, Tag
from .models import Correspondent, Document, DocumentType, Log, Tag, \
SavedView, SavedViewFilterRule
class CorrespondentAdmin(admin.ModelAdmin):
@ -131,8 +132,22 @@ class LogAdmin(admin.ModelAdmin):
list_display_links = ("created", "message")
class RuleInline(admin.TabularInline):
model = SavedViewFilterRule
class SavedViewAdmin(admin.ModelAdmin):
list_display = ("name", "user")
inlines = [
RuleInline
]
admin.site.register(Correspondent, CorrespondentAdmin)
admin.site.register(Tag, TagAdmin)
admin.site.register(DocumentType, DocumentTypeAdmin)
admin.site.register(Document, DocumentAdmin)
admin.site.register(Log, LogAdmin)
admin.site.register(SavedView, SavedViewAdmin)

View File

@ -0,0 +1,37 @@
# Generated by Django 3.1.4 on 2020-12-12 14:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('documents', '1006_auto_20201208_2209'),
]
operations = [
migrations.CreateModel(
name='SavedView',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)),
('show_on_dashboard', models.BooleanField()),
('show_in_sidebar', models.BooleanField()),
('sort_field', models.CharField(max_length=128)),
('sort_reverse', models.BooleanField(default=False)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='SavedViewFilterRule',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('rule_type', models.PositiveIntegerField(choices=[(0, 'Title contains'), (1, 'Content contains'), (2, 'ASN is'), (3, 'Correspondent is'), (4, 'Document type is'), (5, 'Is in inbox'), (6, 'Has tag'), (7, 'Has any tag'), (8, 'Created before'), (9, 'Created after'), (10, 'Created year is'), (11, 'Created month is'), (12, 'Created day is'), (13, 'Added before'), (14, 'Added after'), (15, 'Modified before'), (16, 'Modified after'), (17, 'Does not have tag')])),
('value', models.CharField(max_length=128)),
('saved_view', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='filter_rules', to='documents.savedview')),
],
),
]

View File

@ -9,6 +9,7 @@ import pathvalidate
import dateutil.parser
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
@ -305,6 +306,47 @@ class Log(models.Model):
return self.message
class SavedView(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=128)
show_on_dashboard = models.BooleanField()
show_in_sidebar = models.BooleanField()
sort_field = models.CharField(max_length=128)
sort_reverse = models.BooleanField(default=False)
class SavedViewFilterRule(models.Model):
RULE_TYPES = [
(0, "Title contains"),
(1, "Content contains"),
(2, "ASN is"),
(3, "Correspondent is"),
(4, "Document type is"),
(5, "Is in inbox"),
(6, "Has tag"),
(7, "Has any tag"),
(8, "Created before"),
(9, "Created after"),
(10, "Created year is"),
(11, "Created month is"),
(12, "Created day is"),
(13, "Added before"),
(14, "Added after"),
(15, "Modified before"),
(16, "Modified after"),
(17, "Does not have tag"),
]
saved_view = models.ForeignKey(SavedView, on_delete=models.CASCADE, related_name="filter_rules")
rule_type = models.PositiveIntegerField(choices=RULE_TYPES)
value = models.CharField(max_length=128)
# TODO: why is this in the models file?
class FileInfo:

View File

@ -3,7 +3,8 @@ from django.utils.text import slugify
from rest_framework import serializers
from rest_framework.fields import SerializerMethodField
from .models import Correspondent, Tag, Document, Log, DocumentType
from .models import Correspondent, Tag, Document, Log, DocumentType, \
SavedView, SavedViewFilterRule
from .parsers import is_mime_type_supported
@ -140,6 +141,39 @@ class LogSerializer(serializers.ModelSerializer):
)
class SavedViewFilterRuleSerializer(serializers.ModelSerializer):
class Meta:
model = SavedViewFilterRule
fields = ["rule_type", "value"]
class SavedViewSerializer(serializers.ModelSerializer):
filter_rules = SavedViewFilterRuleSerializer(many=True)
class Meta:
model = SavedView
depth = 1
fields = ["id", "name", "show_on_dashboard", "show_in_sidebar",
"sort_field", "sort_reverse", "filter_rules"]
def update(self, instance, validated_data):
rules_data = validated_data.pop('filter_rules')
super(SavedViewSerializer, self).update(instance, validated_data)
SavedViewFilterRule.objects.filter(saved_view=instance).delete()
for rule_data in rules_data:
SavedViewFilterRule.objects.create(saved_view=instance, **rule_data)
return instance
def create(self, validated_data):
rules_data = validated_data.pop('filter_rules')
saved_view = SavedView.objects.create(**validated_data)
for rule_data in rules_data:
SavedViewFilterRule.objects.create(saved_view=saved_view, **rule_data)
return saved_view
class PostDocumentSerializer(serializers.Serializer):
document = serializers.FileField(

View File

@ -38,7 +38,7 @@ from .filters import (
DocumentTypeFilterSet,
LogFilterSet
)
from .models import Correspondent, Document, Log, Tag, DocumentType
from .models import Correspondent, Document, Log, Tag, DocumentType, SavedView
from .parsers import get_parser_class_for_mime_type
from .serialisers import (
CorrespondentSerializer,
@ -46,7 +46,8 @@ from .serialisers import (
LogSerializer,
TagSerializer,
DocumentTypeSerializer,
PostDocumentSerializer
PostDocumentSerializer,
SavedViewSerializer
)
@ -240,6 +241,22 @@ class LogViewSet(ReadOnlyModelViewSet):
ordering_fields = ("created",)
class SavedViewViewSet(ModelViewSet):
model = SavedView
queryset = SavedView.objects.all()
serializer_class = SavedViewSerializer
pagination_class = StandardPagination
permission_classes = (IsAuthenticated,)
def get_queryset(self):
user = self.request.user
return SavedView.objects.filter(user=user)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
class PostDocumentView(APIView):
permission_classes = (IsAuthenticated,)

View File

@ -17,7 +17,8 @@ from documents.views import (
IndexView,
SearchAutoCompleteView,
StatisticsView,
PostDocumentView
PostDocumentView,
SavedViewViewSet
)
from paperless.views import FaviconView
@ -27,6 +28,7 @@ api_router.register(r"document_types", DocumentTypeViewSet)
api_router.register(r"documents", DocumentViewSet)
api_router.register(r"logs", LogViewSet)
api_router.register(r"tags", TagViewSet)
api_router.register(r"saved_views", SavedViewViewSet)
urlpatterns = [