diff --git a/apps/enm/tasks.py b/apps/enm/tasks.py index ef5a1375..1bfa0f90 100644 --- a/apps/enm/tasks.py +++ b/apps/enm/tasks.py @@ -1,5 +1,4 @@ # Create your tasks here -from __future__ import absolute_import, unicode_literals from apps.utils.tasks import CustomTask from celery import shared_task from apps.enm.models import MpLogx, Mpoint, MpointStat, EnStat, EnStat2, Xscript @@ -96,9 +95,9 @@ def db_ins_mplogx(): cursor.execute(query, (bill_date, tuple(batchs))) rows = cursor.fetchall() # 获取数据后保存至本地 if rows: - bill_date = rows[-1][-1] + bill_date_x = rows[-1][-1] db_insert_mplogx_batch(rows) - update_sysconfig({'enm1': {'bill_date': str(bill_date)}}) + update_sysconfig({'enm1': {'bill_date': bill_date_x.strftime('%Y-%m-%d %H:%M:%S')}}) diff --git a/apps/mtm/migrations/0048_auto_20241218_1431.py b/apps/mtm/migrations/0048_auto_20241218_1431.py new file mode 100644 index 00000000..e9e39946 --- /dev/null +++ b/apps/mtm/migrations/0048_auto_20241218_1431.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.12 on 2024-12-18 06:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0047_route_div_number'), + ] + + operations = [ + migrations.AddField( + model_name='material', + name='tracking', + field=models.PositiveSmallIntegerField(choices=[(10, '批次'), (20, '单件')], default=10, verbose_name='追踪方式'), + ), + migrations.AlterField( + model_name='material', + name='sort', + field=models.FloatField(default=1, verbose_name='排序'), + ), + ] diff --git a/apps/mtm/models.py b/apps/mtm/models.py index 193888c3..31756949 100644 --- a/apps/mtm/models.py +++ b/apps/mtm/models.py @@ -55,6 +55,9 @@ class Material(CommonAModel): (MA_TYPE_OFFICE, '办公用品') ) + MA_TRACKING_BATCH = 10 + MA_TRACKING_SINGLE = 20 + name = models.CharField('名称', max_length=50) cate = models.CharField('大类', max_length=20, default='', blank=True) number = models.CharField('编号', max_length=100, null=True, blank=True) @@ -66,8 +69,11 @@ class Material(CommonAModel): type = models.PositiveSmallIntegerField( '物料类型', choices=type_choices, default=1, help_text=str(type_choices)) testitems = models.JSONField('检测项目', default=list, blank=True) - sort = models.PositiveSmallIntegerField('排序', default=1) + sort = models.FloatField('排序', default=1) unit = models.CharField('基准计量单位', default='个', max_length=10) + tracking = models.PositiveSmallIntegerField("追踪方式", default=10, + choices=((MA_TRACKING_BATCH, '批次'), + (MA_TRACKING_SINGLE, '单件'))) count = models.DecimalField('总库存', max_digits=14, decimal_places=3, default=0) count_mb = models.DecimalField('仓库库存', max_digits=14, decimal_places=3, default=0) count_wm = models.DecimalField('车间库存', max_digits=14, decimal_places=3, default=0) diff --git a/apps/mtm/serializers.py b/apps/mtm/serializers.py index cf41fa79..61cd2495 100644 --- a/apps/mtm/serializers.py +++ b/apps/mtm/serializers.py @@ -183,7 +183,7 @@ class RouteSerializer(CustomModelSerializer): """ material = instance.material process = instance.process - material_out = Material.objects.get_queryset(all=True).filter(type=Material.MA_TYPE_HALFGOOD, parent=material, process=process).first() + material_out: Material = Material.objects.get_queryset(all=True).filter(type=Material.MA_TYPE_HALFGOOD, parent=material, process=process).first() if material_out: material_out.is_deleted = False if material_out.parent == material: @@ -191,6 +191,7 @@ class RouteSerializer(CustomModelSerializer): material_out.model = material.model material_out.specification = material.specification material_out.cate = material.cate + material_out.tracking = material.tracking material_out.save() instance.material_out = material_out instance.save() @@ -201,6 +202,7 @@ class RouteSerializer(CustomModelSerializer): if material_out.parent is None: material_out.parent = material material_out.cate = material.cate + material_out.tracking = material.tracking material_out.save() instance.material_out = material_out instance.save() @@ -212,6 +214,7 @@ class RouteSerializer(CustomModelSerializer): 'model': material.model, 'type': Material.MA_TYPE_HALFGOOD, 'cate': material.cate, + 'tracking': material.tracking, 'create_by': self.request.user, 'update_by': self.request.user, }) diff --git a/apps/qm/filters.py b/apps/qm/filters.py index 162c793e..71585306 100644 --- a/apps/qm/filters.py +++ b/apps/qm/filters.py @@ -1,5 +1,6 @@ from django_filters import rest_framework as filters -from apps.qm.models import QuaStat, TestItem, FtestWork +from apps.qm.models import QuaStat, TestItem, FtestWork, Qct +from apps.utils.filters import MyJsonListFilter class QuaStatFilter(filters.FilterSet): @@ -14,6 +15,17 @@ class QuaStatFilter(filters.FilterSet): "sflog__end_time": ["day", "month", "year", "lt"], } +class QctFilter(filters.FilterSet): + tags = MyJsonListFilter(label="tags查询,分隔") + + class Meta: + model = Qct + fields = { + "testitems": ["exact"], + "defects": ["exact"], + "qctmat__material": ["exact"], + "qctmat__tracing": ["exact"], + } class TestItemFilter(filters.FilterSet): tags__contains = filters.CharFilter(field_name='tags', lookup_expr='contains') diff --git a/apps/qm/migrations/0029_auto_20241219_1509.py b/apps/qm/migrations/0029_auto_20241219_1509.py new file mode 100644 index 00000000..6162dcba --- /dev/null +++ b/apps/qm/migrations/0029_auto_20241219_1509.py @@ -0,0 +1,102 @@ +# Generated by Django 3.2.12 on 2024-12-19 07:09 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('mtm', '0048_auto_20241218_1431'), + ('qm', '0028_defect'), + ] + + operations = [ + migrations.CreateModel( + name='Qct', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('name', models.CharField(max_length=50, verbose_name='名称')), + ('number', models.CharField(max_length=20, verbose_name='编号')), + ('tags', models.JSONField(blank=True, default=list, verbose_name='检测类型')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qct_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='QctTestItem', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('note', models.TextField(blank=True, null=True, verbose_name='备注')), + ('sort', models.FloatField(default=1, verbose_name='排序')), + ('qct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.qct', verbose_name='质检模板')), + ('testitem', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='qm.testitem', verbose_name='检测项')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='QctMat', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('tracing', models.CharField(choices=[('test', '检测项'), ('defect', '缺陷项')], default='test', help_text="(('test', '检测项'), ('defect', '缺陷项'))", max_length=20, verbose_name='追溯层级')), + ('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料')), + ('qct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.qct', verbose_name='质检模板')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='QctDefect', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')), + ('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')), + ('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')), + ('rule_expression', models.TextField(blank=True, null=True, verbose_name='判定表达式')), + ('note', models.TextField(blank=True, null=True, verbose_name='备注')), + ('sort', models.FloatField(default=1, verbose_name='排序')), + ('defect', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.defect', verbose_name='缺陷项')), + ('qct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qm.qct', verbose_name='质检模板')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='qct', + name='defects', + field=models.ManyToManyField(blank=True, through='qm.QctDefect', to='qm.Defect', verbose_name='缺陷项'), + ), + migrations.AddField( + model_name='qct', + name='materials', + field=models.ManyToManyField(blank=True, through='qm.QctMat', to='mtm.Material', verbose_name='物料'), + ), + migrations.AddField( + model_name='qct', + name='testitems', + field=models.ManyToManyField(blank=True, through='qm.QctTestItem', to='qm.TestItem', verbose_name='检测项'), + ), + migrations.AddField( + model_name='qct', + name='update_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='qct_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'), + ), + ] diff --git a/apps/qm/migrations/0030_auto_20241220_1544.py b/apps/qm/migrations/0030_auto_20241220_1544.py new file mode 100644 index 00000000..5465467b --- /dev/null +++ b/apps/qm/migrations/0030_auto_20241220_1544.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.12 on 2024-12-20 07:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('qm', '0029_auto_20241219_1509'), + ] + + operations = [ + migrations.AddField( + model_name='testitem', + name='affects', + field=models.JSONField(blank=True, default=list, verbose_name='影响项列表'), + ), + migrations.AddField( + model_name='testitem', + name='formula', + field=models.TextField(blank=True, null=True, verbose_name='计算公式'), + ), + migrations.AddField( + model_name='testitem', + name='readonly', + field=models.BooleanField(default=False, verbose_name='只读'), + ), + ] diff --git a/apps/qm/migrations/0031_auto_20241223_1050.py b/apps/qm/migrations/0031_auto_20241223_1050.py new file mode 100644 index 00000000..63e6fb81 --- /dev/null +++ b/apps/qm/migrations/0031_auto_20241223_1050.py @@ -0,0 +1,29 @@ +# Generated by Django 3.2.12 on 2024-12-23 02:50 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('qm', '0030_auto_20241220_1544'), + ] + + operations = [ + migrations.AlterField( + model_name='qctdefect', + name='qct', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='qctdefect', to='qm.qct', verbose_name='质检模板'), + ), + migrations.AlterField( + model_name='qctmat', + name='qct', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='qctmat', to='qm.qct', verbose_name='质检模板'), + ), + migrations.AlterField( + model_name='qcttestitem', + name='qct', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='qcttestitem', to='qm.qct', verbose_name='质检模板'), + ), + ] diff --git a/apps/qm/models.py b/apps/qm/models.py index 931f183c..748139c4 100644 --- a/apps/qm/models.py +++ b/apps/qm/models.py @@ -21,6 +21,7 @@ class Defect(CommonAModel): def __str__(self): return self.name + class NotOkOption(models.TextChoices): # 不合格项 zw = "zw", _("炸纹") @@ -119,11 +120,62 @@ class TestItem(CommonAModel): mcate_tags = models.JSONField('物料系列标签', default=list, blank=True) sort = models.PositiveSmallIntegerField('排序', default=1) description = models.TextField('描述', default='') + readonly = models.BooleanField('只读', default=False) + formula = models.TextField('计算公式', null=True, blank=True) + affects = models.JSONField('影响项列表', default=list, blank=True) class Meta: ordering = ['sort', '-create_time'] +QC_T = 'test' +QC_D = 'defect' + +QC_TRACE_CHOICES = ( + (QC_T, '检测项'), + (QC_D, '缺陷项') +) + +class Qct(CommonAModel): + # 检测模板 + name = models.CharField(max_length=50, verbose_name="名称") + number = models.CharField(max_length=20, verbose_name="编号") + tags = models.JSONField('检测类型', default=list, blank=True) + testitems = models.ManyToManyField(TestItem, verbose_name="检测项", blank=True, through='qm.qcttestitem') + defects = models.ManyToManyField(Defect, verbose_name="缺陷项", blank=True, through='qm.qctdefect') + materials = models.ManyToManyField(Material, verbose_name="物料", blank=True, through='qm.qctmat') + + @property + def qct_testitems(self): + return QctTestItem.objects.filter(qct=self) + + @property + def qct_defects(self): + return QctDefect.objects.filter(qct=self) + + @property + def qct_mats(self): + return QctMat.objects.filter(qct=self) + +class QctTestItem(BaseModel): + qct = models.ForeignKey(Qct, verbose_name="质检模板", on_delete=models.CASCADE, related_name="qcttestitem") + testitem = models.ForeignKey(TestItem, verbose_name="检测项", on_delete=models.CASCADE, null=True, blank=True) + note = models.TextField('备注', null=True, blank=True) + sort = models.FloatField('排序', default=1) + +class QctDefect(BaseModel): + qct = models.ForeignKey(Qct, verbose_name="质检模板", on_delete=models.CASCADE, related_name="qctdefect") + defect = models.ForeignKey(Defect, verbose_name="缺陷项", on_delete=models.CASCADE) + rule_expression = models.TextField('判定表达式', null=True, blank=True) + note = models.TextField('备注', null=True, blank=True) + sort = models.FloatField('排序', default=1) + +class QctMat(BaseModel): + qct = models.ForeignKey(Qct, verbose_name="质检模板", on_delete=models.CASCADE, related_name="qctmat") + material = models.ForeignKey(Material, verbose_name="物料", on_delete=models.CASCADE) + tracing = models.CharField('追溯层级', default=QC_T, choices=QC_TRACE_CHOICES, max_length=20, help_text=str(QC_TRACE_CHOICES)) + + class QuaStat(CommonBDModel): """ 质量数据表 diff --git a/apps/qm/serializers.py b/apps/qm/serializers.py index 66f95b38..9bc6351b 100644 --- a/apps/qm/serializers.py +++ b/apps/qm/serializers.py @@ -1,4 +1,5 @@ -from apps.qm.models import QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest, NotOkOption, Defect +from apps.qm.models import (QuaStat, TestItem, Ftest, FtestItem, FtestWork, Ptest, + NotOkOption, Defect, Qct, QctTestItem, QctMat, QctDefect) from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE from apps.utils.serializers import CustomModelSerializer from rest_framework import serializers @@ -29,6 +30,41 @@ class TestItemSerializer(CustomModelSerializer): fields = '__all__' read_only_fields = EXCLUDE_FIELDS +class QctSerializer(CustomModelSerializer): + class Meta: + model = Qct + fields = '__all__' + read_only_fields = EXCLUDE_FIELDS + +class QctTestItemSerializer(CustomModelSerializer): + testitem_name = serializers.CharField(source='testitem.name', read_only=True) + testitem_description = serializers.CharField(source='testitem.description', read_only=True) + testitem_field_type = serializers.CharField(source='testitem.field_type', read_only=True) + testitem_choices = serializers.CharField(source='testitem.choices', read_only=True) + class Meta: + model = QctTestItem + fields = '__all__' + +class QctDefectSerializer(CustomModelSerializer): + defect_name = serializers.CharField(source='defect.name', read_only=True) + class Meta: + model = QctDefect + fields = '__all__' + +class QctMatSerializer(CustomModelSerializer): + material_name = serializers.StringRelatedField(source='material', read_only=True) + class Meta: + model = QctMat + fields = '__all__' + +class QctDetailSerializer(CustomModelSerializer): + qct_testitems = QctTestItemSerializer(many=True, read_only=True) + qct_defects = QctDefectSerializer(many=True, read_only=True) + qct_mats = QctMatSerializer(many=True, read_only=True) + class Meta: + model = Qct + fields = '__all__' + read_only_fields = EXCLUDE_FIELDS class QuaStatSerializer(CustomModelSerializer): sflog = serializers.PrimaryKeyRelatedField( diff --git a/apps/qm/urls.py b/apps/qm/urls.py index a0f5c777..879f266e 100644 --- a/apps/qm/urls.py +++ b/apps/qm/urls.py @@ -3,7 +3,7 @@ from rest_framework.routers import DefaultRouter from apps.qm.views import (QuaStatViewSet, TestItemViewSet, FtestWorkViewSet, FtestViewSet, PtestViewSet, - NotOkOptionView, DefectViewSet) + NotOkOptionView, DefectViewSet, QctViewSet, QctTestItemViewSet, QctDefectViewSet, QctMatViewSet) API_BASE_URL = 'api/qm/' HTML_BASE_URL = 'qm/' @@ -15,6 +15,10 @@ router.register('ftest', FtestViewSet, basename='ftest') router.register('ftestwork', FtestWorkViewSet, basename='ftestwork') router.register('ptest', PtestViewSet, basename='ptest') router.register("defect", DefectViewSet, basename="defect") +router.register('qct', QctViewSet, basename='qct') +router.register('qcttestitem', QctTestItemViewSet, basename='qcttestitem') +router.register('qctdefect', QctDefectViewSet, basename="qctdefect") +router.register('qctmat', QctMatViewSet, basename='qctmat') urlpatterns = [ path(API_BASE_URL, include(router.urls)), path(API_BASE_URL + 'notok_option/', NotOkOptionView.as_view()), diff --git a/apps/qm/views.py b/apps/qm/views.py index fa803a8c..1837be9b 100644 --- a/apps/qm/views.py +++ b/apps/qm/views.py @@ -3,9 +3,11 @@ from rest_framework.decorators import action from rest_framework.exceptions import ParseError from rest_framework.views import APIView from rest_framework.serializers import Serializer -from apps.qm.models import QuaStat, TestItem, Ftest, Ptest, FtestWork +from apps.qm.models import QuaStat, NotOkOption, Ftest, Ptest, FtestWork +from apps.qm.models import TestItem, Defect, Qct, QctTestItem, QctMat, QctDefect from apps.qm.serializers import QuaStatSerializer, TestItemSerializer, QuaStatUpdateSerializer, FtestSerializer, PtestSerializer, \ - FtestWorkCreateUpdateSerializer, FtestWorkSerializer, DefectSerializer + FtestWorkCreateUpdateSerializer, FtestWorkSerializer, DefectSerializer, QctSerializer, QctTestItemSerializer, QctDefectSerializer, QctMatSerializer, \ + QctDetailSerializer from apps.qm.tasks import cal_quastat_sflog from rest_framework.response import Response from apps.utils.mixins import BulkUpdateModelMixin @@ -13,9 +15,8 @@ import datetime from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from apps.wpm.models import SfLog -from apps.qm.filters import QuaStatFilter, TestItemFilter, FtestWorkFilter +from apps.qm.filters import QuaStatFilter, TestItemFilter, FtestWorkFilter, QctFilter from django.db import transaction -from apps.qm.models import NotOkOption, Defect from apps.qm.services import ftestwork_submit from apps.utils.thread import MyThread from apps.wpm.services_2 import get_alldata_with_batch_and_store @@ -24,7 +25,7 @@ from apps.wf.models import State class DefectViewSet(CustomModelViewSet): """ - list:缺陷项 + 缺陷项 缺陷项 """ @@ -33,6 +34,52 @@ class DefectViewSet(CustomModelViewSet): filterset_fields = ["cate", "okcate"] search_fields = ["name", "code"] +class QctViewSet(CustomModelViewSet): + """ + 检测模板 + + 检测模板 + """ + queryset = Qct.objects.all() + serializer_class = QctSerializer + retrieve_serializer_class = QctDetailSerializer + filterset_class = QctFilter + search_fields = ["name", "number"] + +class QctTestItemViewSet(CustomModelViewSet): + """检测模板项 + + 检测模板项 + """ + perms_map = {"get": "*", "post": "qct.update", "put": "qct.update", "delete": "qct.update"} + queryset = QctTestItem.objects.all() + serializer_class = QctTestItemSerializer + select_related_fields = ["qct", "testitem"] + filterset_fields = ["qct", "testitem"] + ordering = ["qct", "sort"] + +class QctDefectViewSet(CustomModelViewSet): + """检测缺陷项 + + 检测缺陷项 + """ + perms_map = {"get": "*", "post": "qct.update", "put": "qct.update", "delete": "qct.update"} + queryset = QctDefect.objects.all() + serializer_class = QctDefectSerializer + select_related_fields = ["qct", "defect"] + filterset_fields = ["qct", "defect"] + ordering = ["qct", "sort"] + +class QctMatViewSet(CustomModelViewSet): + """检测物料 + + 检测物料 + """ + perms_map = {"get": "*", "post": "qct.update", "put": "qct.update", "delete": "qct.update"} + queryset = QctMat.objects.all() + serializer_class = QctMatSerializer + filterset_fields = ["qct", "material"] + class NotOkOptionView(APIView): perms_map = {'get': '*'} @@ -58,6 +105,18 @@ class TestItemViewSet(CustomModelViewSet): search_fields = ['tags', 'name', 'number', 'mcate_tags'] ordering = ['id'] + def add_info_for_list(self, data): + affects_list = [i['affects'] for i in data] + affectIds = [] + for item in affects_list: + affectIds.extend(item) + affects = TestItem.objects.filter(id__in=affectIds).values_list('id', 'name') + affects_dict = dict(affects) + for item in data: + affects = item["affects"] + item["affects_name"] = ";".join([affects_dict.get(x, '未知') for x in affects]) + return data + class QuaStatViewSet(ListModelMixin, BulkUpdateModelMixin, CustomGenericViewSet): """ diff --git a/apps/utils/mixins.py b/apps/utils/mixins.py index 67931b84..c7595057 100755 --- a/apps/utils/mixins.py +++ b/apps/utils/mixins.py @@ -185,11 +185,7 @@ class CustomListModelMixin(ListModelMixin): type=openapi.TYPE_STRING, required=False), ]) def list(self, request, *args, **kwargs): - """ - 获取列表 - 获取列表 - """ queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset)