Reduce duplication with filters (#4583)

* Reduce duplication with filters

* fix typo

* fix naming
This commit is contained in:
Matthias Mair 2023-04-05 00:46:36 +02:00 committed by GitHub
parent 508dd5425d
commit 3294b37ef0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 74 additions and 185 deletions

View File

@ -5,15 +5,14 @@ from django.db import transaction
from django.http import JsonResponse
from django.utils.translation import gettext_lazy as _
from django_filters.rest_framework import DjangoFilterBackend
from django_q.models import OrmQ
from rest_framework import filters, permissions
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.serializers import ValidationError
from rest_framework.views import APIView
import users.models
from InvenTree.filters import InvenTreeSearchFilter
from InvenTree.filters import SEARCH_ORDER_FILTER
from InvenTree.mixins import ListCreateAPI
from InvenTree.permissions import RolePermission
from part.templatetags.inventree_extras import plugins_info
@ -202,11 +201,7 @@ class AttachmentMixin:
RolePermission,
]
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
def perform_create(self, serializer):
"""Save the user information when a file is uploaded."""

View File

@ -1,11 +1,12 @@
"""General filters for InvenTree."""
from rest_framework.filters import OrderingFilter, SearchFilter
from django_filters import rest_framework as rest_filters
from rest_framework import filters
from InvenTree.helpers import str2bool
class InvenTreeSearchFilter(SearchFilter):
class InvenTreeSearchFilter(filters.SearchFilter):
"""Custom search filter which allows adjusting of search terms dynamically"""
def get_search_fields(self, view, request):
@ -59,7 +60,7 @@ class InvenTreeSearchFilter(SearchFilter):
return terms
class InvenTreeOrderingFilter(OrderingFilter):
class InvenTreeOrderingFilter(filters.OrderingFilter):
"""Custom OrderingFilter class which allows aliased filtering of related fields.
To use, simply specify this filter in the "filter_backends" section.
@ -130,3 +131,21 @@ class InvenTreeOrderingFilter(OrderingFilter):
ordering.append(a)
return ordering
SEARCH_ORDER_FILTER = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
SEARCH_ORDER_FILTER_ALIAS = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
ORDER_FILTER = [
rest_filters.DjangoFilterBackend,
filters.OrderingFilter,
]

View File

@ -11,7 +11,6 @@ from django_filters import rest_framework as rest_filters
from InvenTree.api import AttachmentMixin, APIDownloadMixin, ListCreateDestroyAPIView, MetadataView, StatusView
from InvenTree.helpers import str2bool, isNull, DownloadFile
from InvenTree.filters import InvenTreeOrderingFilter, InvenTreeSearchFilter
from InvenTree.status_codes import BuildStatus
from InvenTree.mixins import CreateAPI, RetrieveUpdateDestroyAPI, ListCreateAPI
@ -20,6 +19,7 @@ import build.serializers
from build.models import Build, BuildItem, BuildOrderAttachment
import part.models
from users.models import Owner
from InvenTree.filters import SEARCH_ORDER_FILTER_ALIAS
class BuildFilter(rest_filters.FilterSet):
@ -99,11 +99,7 @@ class BuildList(APIDownloadMixin, ListCreateAPI):
serializer_class = build.serializers.BuildSerializer
filterset_class = BuildFilter
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_fields = [
'reference',

View File

@ -7,10 +7,9 @@ from django.urls import include, path, re_path
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django_filters.rest_framework import DjangoFilterBackend
from django_q.tasks import async_task
from djmoney.contrib.exchange.models import ExchangeBackend, Rate
from rest_framework import filters, permissions, serializers
from rest_framework import permissions, serializers
from rest_framework.exceptions import NotAcceptable, NotFound
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
@ -20,7 +19,7 @@ import common.models
import common.serializers
from InvenTree.api import BulkDeleteMixin
from InvenTree.config import CONFIG_LOOKUPS
from InvenTree.filters import InvenTreeSearchFilter
from InvenTree.filters import ORDER_FILTER, SEARCH_ORDER_FILTER
from InvenTree.helpers import inheritors
from InvenTree.mixins import (ListAPI, RetrieveAPI, RetrieveUpdateAPI,
RetrieveUpdateDestroyAPI)
@ -168,11 +167,7 @@ class SettingsList(ListAPI):
This is inheritted by all list views for settings.
"""
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
ordering_fields = [
'pk',
@ -340,11 +335,7 @@ class NotificationList(NotificationMessageMixin, BulkDeleteMixin, ListAPI):
permission_classes = [permissions.IsAuthenticated, ]
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
ordering_fields = [
'category',
@ -409,10 +400,7 @@ class NewsFeedMixin:
class NewsFeedEntryList(NewsFeedMixin, BulkDeleteMixin, ListAPI):
"""List view for all news items."""
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
]
filter_backends = ORDER_FILTER
ordering_fields = [
'published',

View File

@ -5,12 +5,12 @@ from django.urls import include, path, re_path
from django_filters import rest_framework as rest_filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters
import part.models
from InvenTree.api import (AttachmentMixin, ListCreateDestroyAPIView,
MetadataView)
from InvenTree.filters import InvenTreeOrderingFilter, InvenTreeSearchFilter
from InvenTree.filters import (ORDER_FILTER, SEARCH_ORDER_FILTER,
SEARCH_ORDER_FILTER_ALIAS)
from InvenTree.helpers import str2bool
from InvenTree.mixins import ListCreateAPI, RetrieveUpdateDestroyAPI
@ -44,11 +44,7 @@ class CompanyList(ListCreateAPI):
return queryset
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'is_customer',
@ -114,11 +110,7 @@ class ContactList(ListCreateDestroyAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'company',
@ -192,11 +184,7 @@ class ManufacturerPartList(ListCreateDestroyAPIView):
return self.serializer_class(*args, **kwargs)
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
search_fields = [
'manufacturer__name',
@ -287,11 +275,7 @@ class ManufacturerPartParameterList(ListCreateDestroyAPIView):
return self.serializer_class(*args, **kwargs)
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
search_fields = [
'name',
@ -388,11 +372,7 @@ class SupplierPartList(ListCreateDestroyAPIView):
serializer_class = SupplierPartSerializer
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_fields = [
'SKU',
@ -493,10 +473,7 @@ class SupplierPriceBreakList(ListCreateAPI):
return self.serializer_class(*args, **kwargs)
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
]
filter_backends = ORDER_FILTER
ordering_fields = [
'quantity',

View File

@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework as rest_filters
from django_ical.views import ICalFeed
from rest_framework import filters, status
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.response import Response
@ -21,7 +21,7 @@ from common.settings import settings
from company.models import SupplierPart
from InvenTree.api import (APIDownloadMixin, AttachmentMixin,
ListCreateDestroyAPIView, MetadataView, StatusView)
from InvenTree.filters import InvenTreeOrderingFilter, InvenTreeSearchFilter
from InvenTree.filters import SEARCH_ORDER_FILTER, SEARCH_ORDER_FILTER_ALIAS
from InvenTree.helpers import DownloadFile, str2bool
from InvenTree.mixins import (CreateAPI, ListAPI, ListCreateAPI,
RetrieveUpdateDestroyAPI)
@ -61,11 +61,7 @@ class GeneralExtraLineList(APIDownloadMixin):
return queryset
filter_backends = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter
]
filter_backends = SEARCH_ORDER_FILTER
ordering_fields = [
'title',
@ -307,11 +303,7 @@ class PurchaseOrderList(PurchaseOrderMixin, APIDownloadMixin, ListCreateAPI):
return queryset
filter_backends = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_field_aliases = {
'reference': ['reference_int', 'reference'],
@ -508,11 +500,7 @@ class PurchaseOrderLineItemList(PurchaseOrderLineItemMixin, APIDownloadMixin, Li
return DownloadFile(filedata, filename)
filter_backends = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_field_aliases = {
'MPN': 'part__manufacturer_part__MPN',
@ -693,11 +681,7 @@ class SalesOrderList(SalesOrderMixin, APIDownloadMixin, ListCreateAPI):
return queryset
filter_backends = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_field_aliases = {
'reference': ['reference_int', 'reference'],
@ -817,11 +801,7 @@ class SalesOrderLineItemList(SalesOrderLineItemMixin, APIDownloadMixin, ListCrea
return DownloadFile(filedata, filename)
filter_backends = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter
]
filter_backends = SEARCH_ORDER_FILTER
ordering_fields = [
'part__name',
@ -1154,11 +1134,7 @@ class ReturnOrderList(ReturnOrderMixin, APIDownloadMixin, ListCreateAPI):
return DownloadFile(filedata, filename)
filter_backends = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_field_aliases = {
'reference': ['reference_int', 'reference'],
@ -1302,11 +1278,7 @@ class ReturnOrderLineItemList(ReturnOrderLineItemMixin, APIDownloadMixin, ListCr
raise NotImplementedError("download_queryset not yet implemented for this endpoint")
filter_backends = [
rest_filters.DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
ordering_fields = [
'reference',

View File

@ -9,7 +9,7 @@ from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework as rest_filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters, permissions, serializers, status
from rest_framework import permissions, serializers, status
from rest_framework.exceptions import ValidationError
from rest_framework.response import Response
@ -17,7 +17,9 @@ import order.models
from build.models import Build, BuildItem
from InvenTree.api import (APIDownloadMixin, AttachmentMixin,
ListCreateDestroyAPIView, MetadataView)
from InvenTree.filters import InvenTreeOrderingFilter, InvenTreeSearchFilter
from InvenTree.filters import (ORDER_FILTER, SEARCH_ORDER_FILTER,
SEARCH_ORDER_FILTER_ALIAS,
InvenTreeSearchFilter)
from InvenTree.helpers import (DownloadFile, increment_serial_number, isNull,
str2bool, str2int)
from InvenTree.mixins import (CreateAPI, CustomRetrieveUpdateDestroyAPI,
@ -152,11 +154,7 @@ class CategoryList(CategoryMixin, APIDownloadMixin, ListCreateAPI):
return queryset
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'name',
@ -220,10 +218,7 @@ class CategoryTree(ListAPI):
queryset = PartCategory.objects.all()
serializer_class = part_serializers.CategoryTree
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
]
filter_backends = ORDER_FILTER
# Order by tree level (top levels first) and then name
ordering = ['level', 'name']
@ -384,11 +379,7 @@ class PartTestTemplateList(ListCreateAPI):
return queryset
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
InvenTreeSearchFilter,
]
filter_backends = SEARCH_ORDER_FILTER
class PartThumbs(ListAPI):
@ -1224,11 +1215,7 @@ class PartList(PartMixin, APIDownloadMixin, ListCreateAPI):
return queryset
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_fields = [
'name',
@ -1337,11 +1324,7 @@ class PartParameterTemplateList(ListCreateAPI):
queryset = PartParameterTemplate.objects.all()
serializer_class = part_serializers.PartParameterTemplateSerializer
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
InvenTreeSearchFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'name',
@ -1462,10 +1445,7 @@ class PartStocktakeList(ListCreateAPI):
return context
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
]
filter_backends = ORDER_FILTER
ordering_fields = [
'part',
@ -1496,10 +1476,7 @@ class PartStocktakeReportList(ListAPI):
queryset = PartStocktakeReport.objects.all()
serializer_class = part_serializers.PartStocktakeReportSerializer
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
]
filter_backends = ORDER_FILTER
ordering_fields = [
'date',
@ -1731,11 +1708,7 @@ class BomList(BomMixin, ListCreateDestroyAPIView):
return queryset
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
search_fields = [
'reference',
@ -1836,11 +1809,7 @@ class BomItemSubstituteList(ListCreateAPI):
serializer_class = part_serializers.BomItemSubstituteSerializer
queryset = BomItemSubstitute.objects.all()
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'part',

View File

@ -3,13 +3,13 @@
from django.urls import include, path, re_path
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters, permissions, status
from rest_framework import permissions, status
from rest_framework.exceptions import NotFound
from rest_framework.response import Response
import plugin.serializers as PluginSerializers
from common.api import GlobalSettingsPermissions
from InvenTree.filters import InvenTreeSearchFilter
from InvenTree.filters import SEARCH_ORDER_FILTER
from InvenTree.mixins import (CreateAPI, ListAPI, RetrieveUpdateAPI,
RetrieveUpdateDestroyAPI, UpdateAPI)
from InvenTree.permissions import IsSuperuser
@ -57,11 +57,7 @@ class PluginList(ListAPI):
return queryset
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'active',

View File

@ -11,8 +11,7 @@ from django.urls import include, path, re_path
from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework as rest_filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters, status
from rest_framework import status
from rest_framework.response import Response
from rest_framework.serializers import ValidationError
@ -24,7 +23,8 @@ from company.models import Company, SupplierPart
from company.serializers import CompanySerializer, SupplierPartSerializer
from InvenTree.api import (APIDownloadMixin, AttachmentMixin,
ListCreateDestroyAPIView, MetadataView, StatusView)
from InvenTree.filters import InvenTreeOrderingFilter, InvenTreeSearchFilter
from InvenTree.filters import (ORDER_FILTER, SEARCH_ORDER_FILTER,
SEARCH_ORDER_FILTER_ALIAS)
from InvenTree.helpers import (DownloadFile, extract_serial_numbers, isNull,
str2bool, str2int)
from InvenTree.mixins import (CreateAPI, CustomRetrieveUpdateDestroyAPI,
@ -294,11 +294,7 @@ class StockLocationList(APIDownloadMixin, ListCreateAPI):
return queryset
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'name',
@ -333,10 +329,7 @@ class StockLocationTree(ListAPI):
queryset = StockLocation.objects.all()
serializer_class = StockSerializers.LocationTreeSerializer
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
]
filter_backends = ORDER_FILTER
# Order by tree level (top levels first) and then name
ordering = ['level', 'name']
@ -1007,11 +1000,7 @@ class StockList(APIDownloadMixin, ListCreateDestroyAPIView):
return queryset
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
InvenTreeOrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_field_aliases = {
'SKU': 'supplier_part__SKU',
@ -1054,11 +1043,7 @@ class StockAttachmentList(AttachmentMixin, ListCreateDestroyAPIView):
queryset = StockItemAttachment.objects.all()
serializer_class = StockSerializers.StockItemAttachmentSerializer
filter_backends = [
DjangoFilterBackend,
filters.OrderingFilter,
InvenTreeSearchFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'stock_item',
@ -1085,11 +1070,7 @@ class StockItemTestResultList(ListCreateDestroyAPIView):
queryset = StockItemTestResult.objects.all()
serializer_class = StockSerializers.StockItemTestResultSerializer
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'test',
@ -1310,11 +1291,7 @@ class StockTrackingList(ListAPI):
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
filter_backends = [
DjangoFilterBackend,
InvenTreeSearchFilter,
filters.OrderingFilter,
]
filter_backends = SEARCH_ORDER_FILTER
filterset_fields = [
'item',