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)) path('api/v1/', include(router.urls))
] ]

View File

@ -1,9 +1,12 @@
import os import os
from django_filters import NumberFilter
def logs_dir_path(instance, filename): 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}' return f'{instance.ticket.number}/{filename}'
@ -37,3 +40,22 @@ class PageTitleViewMixin:
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['title'] = self.get_title() context['title'] = self.get_title()
return context 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.parsers import FormParser, MultiPartParser
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
# from rest_framework import mixins
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from .models import Archive, Ticket, Platform from .models import Archive, Ticket, Platform
from .forms import TicketForm from .forms import TicketForm
from .filters import ArchiveFilter, TicketFilter
from .utils import PageTitleViewMixin, is_ajax from .utils import PageTitleViewMixin, is_ajax
from .permissions import IsGuestUpload from .permissions import IsGuestUpload
@ -187,6 +189,8 @@ class ArchiveViewSet(viewsets.ModelViewSet):
serializer_class = ArchiveSerializer serializer_class = ArchiveSerializer
parser_classes = (MultiPartParser, FormParser) parser_classes = (MultiPartParser, FormParser)
permission_classes = (IsGuestUpload, ) permission_classes = (IsGuestUpload, )
filter_backends = [DjangoFilterBackend]
filterset_class = ArchiveFilter
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
# ! upload-token protection: # ! upload-token protection:
@ -244,3 +248,9 @@ class TicketViewSet(viewsets.ModelViewSet):
lookup_field = 'number' lookup_field = 'number'
serializer_class = TicketSerializer serializer_class = TicketSerializer
permission_classes = (IsAuthenticated, ) 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', 'django.contrib.staticfiles',
'collector.apps.CollectorConfig', # main app 'collector.apps.CollectorConfig', # main app
'rest_framework', 'rest_framework',
'django_filters',
"crispy_forms", "crispy_forms",
"crispy_bootstrap5", "crispy_bootstrap5",
'django_cleanup.apps.CleanupConfig', # required bottom 'django_cleanup.apps.CleanupConfig', # required bottom
@ -147,6 +148,7 @@ REST_FRAMEWORK = {
'rest_framework.renderers.BrowsableAPIRenderer', 'rest_framework.renderers.BrowsableAPIRenderer',
'rest_framework.parsers.MultiPartParser' 'rest_framework.parsers.MultiPartParser'
], ],
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend', ], # noqa:E501
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', # noqa:E501 # 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', # noqa:E501
# 'PAGE_SIZE': 3, # '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"] docs = ["furo (>=2021.8.17b43,<2021.9.dev0)", "sphinx (>=3.5.0)", "sphinx-notfound-page"]
testing = ["coverage[toml] (>=5.0a4)", "pytest (>=4.6.11)"] 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]] [[package]]
name = "djangorestframework" name = "djangorestframework"
version = "3.14.0" version = "3.14.0"
@ -268,4 +282,4 @@ files = [
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" 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" django-crispy-forms = "^2.0"
crispy-bootstrap5 = "^0.7" crispy-bootstrap5 = "^0.7"
markdown = "^3.4.4" markdown = "^3.4.4"
django-filter = "^23.2"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
flake8 = "^6.0.0" flake8 = "^6.0.0"