Add: simple filters to modelviewsets

This commit is contained in:
Stepan Zhukovsky 2023-08-11 22:12:51 +09:00
parent 3f37ed95ed
commit 94640a70fa
7 changed files with 94 additions and 6 deletions

View File

@ -0,0 +1,39 @@
from django_filters.rest_framework import (
CharFilter,
FilterSet,
NumberFilter,
)
from django_filters import widgets
from .models import Archive, Ticket
from .utils import DateTimeFilterMixin
class ArchiveFilter(DateTimeFilterMixin, FilterSet):
class Meta:
model = Archive
fields = {
'id': ['exact', 'in', 'lte', 'gte'],
'ticket': ['exact', 'in', 'lte', 'gte'],
'time_create': ['exact', 'lte', 'gte']
}
class TicketFilter(DateTimeFilterMixin, FilterSet):
number = NumberFilter(
field_name='number',
widget=widgets.CSVWidget(),
)
user = CharFilter(
field_name='user__username'
)
class Meta:
model = Ticket
fields = {
'id': ['exact', 'in', 'lte', 'gte'],
'number': ['exact', 'contains', 'in', 'lte', 'gte'],
'resolved': ['exact'],
'user': ['exact']
}

View File

@ -77,6 +77,6 @@ urlpatterns = [
# █▀█ █▀▀ █
# -- -- --
# CREATE:
# CRUD:
path('api/v1/', include(router.urls))
]

View File

@ -1,9 +1,12 @@
import os
from django_filters import NumberFilter
def logs_dir_path(instance, filename):
# file will be uploaded to
# MEDIA_ROOT_FOR_SENSITIVE_FILES/<ticket-token>/<filename>
"""
file will be uploaded to
MEDIA_ROOT_FOR_SENSITIVE_FILES/<ticket-token>/<filename>
"""
return f'{instance.ticket.number}/{filename}'
@ -37,3 +40,22 @@ class PageTitleViewMixin:
context = super().get_context_data(**kwargs)
context['title'] = self.get_title()
return context
class DateTimeFilterMixin:
year__gte = NumberFilter(
field_name='time_create',
lookup_expr='year__gte'
)
year__lte = NumberFilter(
field_name='time_create',
lookup_expr='year__lte'
)
month__gte = NumberFilter(
field_name='time_create',
lookup_expr='month__gte'
)
month__lte = NumberFilter(
field_name='time_create',
lookup_expr='month__lte'
)

View File

@ -12,12 +12,14 @@ from rest_framework import status
from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
# from rest_framework import mixins
from rest_framework import viewsets
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from .models import Archive, Ticket, Platform
from .forms import TicketForm
from .filters import ArchiveFilter, TicketFilter
from .utils import PageTitleViewMixin, is_ajax
from .permissions import IsGuestUpload
@ -187,6 +189,8 @@ class ArchiveViewSet(viewsets.ModelViewSet):
serializer_class = ArchiveSerializer
parser_classes = (MultiPartParser, FormParser)
permission_classes = (IsGuestUpload, )
filter_backends = [DjangoFilterBackend]
filterset_class = ArchiveFilter
def create(self, request, *args, **kwargs):
# ! upload-token protection:
@ -244,3 +248,9 @@ class TicketViewSet(viewsets.ModelViewSet):
lookup_field = 'number'
serializer_class = TicketSerializer
permission_classes = (IsAuthenticated, )
filter_backends = [DjangoFilterBackend, filters.SearchFilter]
filterset_class = TicketFilter
search_fields = ['number']
def perform_create(self, serializer):
serializer.save(user=self.request.user)

View File

@ -35,6 +35,7 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'collector.apps.CollectorConfig', # main app
'rest_framework',
'django_filters',
"crispy_forms",
"crispy_bootstrap5",
'django_cleanup.apps.CleanupConfig', # required bottom
@ -147,6 +148,7 @@ REST_FRAMEWORK = {
'rest_framework.renderers.BrowsableAPIRenderer',
'rest_framework.parsers.MultiPartParser'
],
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend', ], # noqa:E501
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', # noqa:E501
# 'PAGE_SIZE': 3,
}

16
poetry.lock generated
View File

@ -96,6 +96,20 @@ develop = ["coverage[toml] (>=5.0a4)", "furo (>=2021.8.17b43,<2021.9.dev0)", "py
docs = ["furo (>=2021.8.17b43,<2021.9.dev0)", "sphinx (>=3.5.0)", "sphinx-notfound-page"]
testing = ["coverage[toml] (>=5.0a4)", "pytest (>=4.6.11)"]
[[package]]
name = "django-filter"
version = "23.2"
description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically."
optional = false
python-versions = ">=3.7"
files = [
{file = "django-filter-23.2.tar.gz", hash = "sha256:2fe15f78108475eda525692813205fa6f9e8c1caf1ae65daa5862d403c6dbf00"},
{file = "django_filter-23.2-py3-none-any.whl", hash = "sha256:d12d8e0fc6d3eb26641e553e5d53b191eb8cec611427d4bdce0becb1f7c172b5"},
]
[package.dependencies]
Django = ">=3.2"
[[package]]
name = "djangorestframework"
version = "3.14.0"
@ -268,4 +282,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "1fc8f57d5dd1b53de4879607d1c7e7c8d9acafd9cbafe4ff64763766d69a4d51"
content-hash = "b42d414f4fc2d5e6e441406720910dce9e6f2c57dab1fb935de691a32715c287"

View File

@ -16,6 +16,7 @@ django-cleanup = "^8.0.0"
django-crispy-forms = "^2.0"
crispy-bootstrap5 = "^0.7"
markdown = "^3.4.4"
django-filter = "^23.2"
[tool.poetry.group.dev.dependencies]
flake8 = "^6.0.0"