Allow filtering on multiple correspondents, doctypes, storage paths

Preserve 'Not assigned' option
Fix default logical operator
Update frontend strings
Fix radio button name overlaps
Use include / exclude with multi-select for OneToOne objects
This commit is contained in:
shamoon
2023-03-10 14:53:32 -08:00
parent 4383550d98
commit 00e17f4d69
15 changed files with 483 additions and 188 deletions

View File

@@ -36,29 +36,30 @@ class DocumentTypeFilterSet(FilterSet):
fields = {"name": CHAR_KWARGS}
class TagsFilter(Filter):
def __init__(self, exclude=False, in_list=False):
class ObjectFilter(Filter):
def __init__(self, exclude=False, in_list=False, field_name=""):
super().__init__()
self.exclude = exclude
self.in_list = in_list
self.field_name = field_name
def filter(self, qs, value):
if not value:
return qs
try:
tag_ids = [int(x) for x in value.split(",")]
object_ids = [int(x) for x in value.split(",")]
except ValueError:
return qs
if self.in_list:
qs = qs.filter(tags__id__in=tag_ids).distinct()
qs = qs.filter(**{f"{self.field_name}__id__in": object_ids}).distinct()
else:
for tag_id in tag_ids:
for obj_id in object_ids:
if self.exclude:
qs = qs.exclude(tags__id=tag_id)
qs = qs.exclude(**{f"{self.field_name}__id": obj_id})
else:
qs = qs.filter(tags__id=tag_id)
qs = qs.filter(**{f"{self.field_name}__id": obj_id})
return qs
@@ -90,11 +91,17 @@ class DocumentFilterSet(FilterSet):
exclude=True,
)
tags__id__all = TagsFilter()
tags__id__all = ObjectFilter(field_name="tags")
tags__id__none = TagsFilter(exclude=True)
tags__id__none = ObjectFilter(field_name="tags", exclude=True)
tags__id__in = TagsFilter(in_list=True)
tags__id__in = ObjectFilter(field_name="tags", in_list=True)
correspondent__id__none = ObjectFilter(field_name="correspondent", exclude=True)
document_type__id__none = ObjectFilter(field_name="document_type", exclude=True)
storage_path__id__none = ObjectFilter(field_name="storage_path", exclude=True)
is_in_inbox = InboxFilter()

View File

@@ -0,0 +1,54 @@
# Generated by Django 4.1.5 on 2023-03-15 07:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("documents", "1033_alter_documenttype_options_alter_tag_options_and_more"),
]
operations = [
migrations.AlterField(
model_name="savedviewfilterrule",
name="rule_type",
field=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"),
(18, "does not have ASN"),
(19, "title or content contains"),
(20, "fulltext query"),
(21, "more like this"),
(22, "has tags in"),
(23, "ASN greater than"),
(24, "ASN less than"),
(25, "storage path is"),
(26, "has correspondent in"),
(27, "does not have correspondent in"),
(28, "has document type in"),
(29, "does not have document type in"),
(30, "has storage path in"),
(31, "does not have storage path in"),
],
verbose_name="rule type",
),
),
]

View File

@@ -447,6 +447,12 @@ class SavedViewFilterRule(models.Model):
(23, _("ASN greater than")),
(24, _("ASN less than")),
(25, _("storage path is")),
(26, _("has correspondent in")),
(27, _("does not have correspondent in")),
(28, _("has document type in")),
(29, _("does not have document type in")),
(30, _("has storage path in")),
(31, _("does not have storage path in")),
]
saved_view = models.ForeignKey(