1
0
forked from erp-dev/erp

fix: added name filter for api_man apis, fixed plate_orders search exclude id (only search via design_code)

This commit is contained in:
2025-12-09 14:15:31 +08:00
parent a36a7e5265
commit 86d0c916ca
8 changed files with 8391 additions and 35 deletions

View File

@@ -2,11 +2,80 @@ from rest_framework import viewsets
from rest_framework.exceptions import PermissionDenied
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import IsAuthenticated, DjangoModelPermissions
from django.contrib.auth.models import Permission
from django_filters.rest_framework import DjangoFilterBackend
from django_filters import rest_framework as dj_filters
from . import serializers
class BaseViewSet(viewsets.ModelViewSet):
class BasicInfoFilterMixin:
"""
提供基于 name/title 的基础过滤能力,自动判定字段,避免重复配置。
"""
filter_backends = [DjangoFilterBackend]
_auto_filterset_cache = {}
def _detect_filter_field(self):
"""
返回 field_name 或 None。
"""
model = getattr(getattr(self, 'queryset', None), 'model', None)
if model is None:
try:
qs = super().get_queryset()
model = getattr(qs, 'model', None)
except Exception:
return None
field_names = {f.name for f in model._meta.get_fields() if hasattr(f, 'name')}
# 优先级name > title > driver_name
if 'name' in field_names:
return 'name'
if 'title' in field_names:
return 'title'
if 'driver_name' in field_names:
return 'driver_name'
return None
def _build_filterset_class(self, model, field):
"""
动态构建 FilterSet参数名直接使用字段名lookup 使用 icontains。
"""
cache_key = (model, field)
if cache_key in self._auto_filterset_cache:
return self._auto_filterset_cache[cache_key]
meta_cls = type(
'Meta',
(),
{
'model': model,
'fields': [field],
},
)
auto_filter_cls = type(
f'{model.__name__}AutoFilter',
(dj_filters.FilterSet,),
{
field: dj_filters.CharFilter(field_name=field, lookup_expr='icontains'),
'Meta': meta_cls,
},
)
self._auto_filterset_cache[cache_key] = auto_filter_cls
return auto_filter_cls
def filter_queryset(self, queryset):
field = self._detect_filter_field()
model = getattr(getattr(self, 'queryset', None), 'model', None)
if not field or not model:
return super().filter_queryset(queryset)
self.filterset_class = self._build_filterset_class(model, field)
return super().filter_queryset(queryset)
class BaseViewSet(BasicInfoFilterMixin, viewsets.ModelViewSet):
pagination_class = LimitOffsetPagination
def get_queryset(self):
@@ -25,9 +94,10 @@ class BaseViewSet(viewsets.ModelViewSet):
raise PermissionDenied("无权限创建该对象")
class QuickInputViewSet(viewsets.ModelViewSet):
queryset = serializers.basic_models.QuickInput.objects
class QuickInputViewSet(BasicInfoFilterMixin, viewsets.ModelViewSet):
queryset = serializers.basic_models.QuickInput.objects.all()
serializer_class = serializers.QuickInputSerializer
pagination_class = LimitOffsetPagination
def filter_queryset(self, queryset):
qs = super().filter_queryset(queryset)