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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user