feat(material): 列表序列化器与筛选扩展
- MaterialListSerializer 补全 A 组字段(规格/应用/优势/成本/星级/施工)
- 新增供应商扩展字段 factory_cooperation_mode/display/province/city
- MaterialSerializer 同步供应商扩展字段供详情使用
- 视图 queryset 增加 select_related('factory','brand')
- 新增筛选: stage / importance_level / factory / cooperation_mode /
landing_project / cost_compare 区间 / score_level>=N / contact_person / handler
- material_category 改为 icontains 模糊匹配
- choices 接口追加 cooperation_mode
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
2b76bbc62a
commit
99e6df0a57
|
|
@ -20,6 +20,10 @@ class MaterialSerializer(serializers.ModelSerializer):
|
|||
"""
|
||||
factory_name = serializers.CharField(source='factory.factory_name', read_only=True)
|
||||
factory_short_name = serializers.CharField(source='factory.short_name', read_only=True)
|
||||
factory_cooperation_mode = serializers.CharField(source='factory.cooperation_mode', read_only=True, default=None)
|
||||
factory_cooperation_mode_display = serializers.SerializerMethodField()
|
||||
factory_province = serializers.CharField(source='factory.province', read_only=True, default=None)
|
||||
factory_city = serializers.CharField(source='factory.city', read_only=True, default=None)
|
||||
brand = serializers.PrimaryKeyRelatedField(
|
||||
queryset=Brand.objects.all(), allow_null=True, required=False
|
||||
)
|
||||
|
|
@ -57,10 +61,15 @@ class MaterialSerializer(serializers.ModelSerializer):
|
|||
'brochure_url', 'quality_level', 'durability_level', 'eco_level',
|
||||
'carbon_level', 'score_level', 'connection_method', 'construction_method',
|
||||
'limit_condition', 'factory', 'factory_name', 'factory_short_name',
|
||||
'factory_cooperation_mode', 'factory_cooperation_mode_display',
|
||||
'factory_province', 'factory_city',
|
||||
'brand', 'brand_name',
|
||||
'status', 'created_at', 'updated_at']
|
||||
read_only_fields = ['id', 'created_at', 'updated_at']
|
||||
|
||||
def get_factory_cooperation_mode_display(self, obj):
|
||||
return obj.factory.get_cooperation_mode_display() if obj.factory and obj.factory.cooperation_mode else None
|
||||
|
||||
def get_brochure_url(self, obj):
|
||||
if obj.brochure:
|
||||
request = self.context.get('request')
|
||||
|
|
@ -85,25 +94,44 @@ class MaterialSerializer(serializers.ModelSerializer):
|
|||
|
||||
class MaterialListSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
材料列表序列化器(简化版)
|
||||
材料列表序列化器(完整字段版,供列表页按需展示列)
|
||||
"""
|
||||
factory_name = serializers.CharField(source='factory.factory_name', read_only=True)
|
||||
factory_short_name = serializers.CharField(source='factory.short_name', read_only=True)
|
||||
factory_cooperation_mode = serializers.CharField(source='factory.cooperation_mode', read_only=True, default=None)
|
||||
factory_cooperation_mode_display = serializers.SerializerMethodField()
|
||||
factory_province = serializers.CharField(source='factory.province', read_only=True, default=None)
|
||||
factory_city = serializers.CharField(source='factory.city', read_only=True, default=None)
|
||||
brand_name = serializers.CharField(source='brand.name', read_only=True)
|
||||
major_category_display = serializers.CharField(source='get_major_category_display', read_only=True)
|
||||
status_display = serializers.CharField(source='get_status_display', read_only=True)
|
||||
stage_display = serializers.CharField(source='get_stage_display', read_only=True)
|
||||
importance_level_display = serializers.CharField(source='get_importance_level_display', read_only=True)
|
||||
replace_type_display = serializers.CharField(source='get_replace_type_display', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Material
|
||||
fields = ['id', 'name', 'major_category', 'major_category_display',
|
||||
fields = ['id', 'name', 'major_category', 'major_category_display',
|
||||
'material_category', 'material_subcategory', 'stage', 'stage_display',
|
||||
'importance_level', 'importance_level_display', 'landing_project',
|
||||
'contact_person', 'contact_phone', 'handler', 'remark', 'factory',
|
||||
'factory_name', 'factory_short_name', 'brand', 'brand_name',
|
||||
'contact_person', 'contact_phone', 'handler', 'remark',
|
||||
'spec', 'standard',
|
||||
'application_scene', 'application_desc',
|
||||
'replace_type', 'replace_type_display',
|
||||
'advantage', 'advantage_desc',
|
||||
'connection_method', 'construction_method', 'limit_condition',
|
||||
'cost_compare', 'cost_desc', 'cases',
|
||||
'quality_level', 'durability_level', 'eco_level',
|
||||
'carbon_level', 'score_level',
|
||||
'factory', 'factory_name', 'factory_short_name',
|
||||
'factory_cooperation_mode', 'factory_cooperation_mode_display',
|
||||
'factory_province', 'factory_city',
|
||||
'brand', 'brand_name',
|
||||
'status', 'status_display']
|
||||
|
||||
def get_factory_cooperation_mode_display(self, obj):
|
||||
return obj.factory.get_cooperation_mode_display() if obj.factory and obj.factory.cooperation_mode else None
|
||||
|
||||
|
||||
class MaterialCategorySerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from rest_framework.parsers import MultiPartParser
|
|||
from .models import Material, MaterialCategory, MaterialSubcategory
|
||||
from .serializers import MaterialSerializer, MaterialListSerializer, MaterialCategorySerializer, MaterialSubcategorySerializer
|
||||
from .importers import import_materials_plan_excel
|
||||
from apps.factory.models import COOPERATION_MODE_CHOICES
|
||||
|
||||
|
||||
def _join_choice_values(values, choices):
|
||||
|
|
@ -149,7 +150,7 @@ class MaterialViewSet(ModelViewSet):
|
|||
"""
|
||||
根据用户角色过滤材料
|
||||
"""
|
||||
queryset = Material.objects.all().order_by('-created_at', '-id')
|
||||
queryset = Material.objects.select_related('factory', 'brand').order_by('-created_at', '-id')
|
||||
|
||||
# 普通用户只能看到自己工厂的材料
|
||||
if self.request.user.role != 'admin':
|
||||
|
|
@ -180,10 +181,10 @@ class MaterialViewSet(ModelViewSet):
|
|||
if major_category:
|
||||
queryset = queryset.filter(major_category=major_category)
|
||||
|
||||
# 支持按材料分类过滤
|
||||
# 支持按材料分类模糊过滤
|
||||
material_category = self.request.query_params.get('material_category')
|
||||
if material_category:
|
||||
queryset = queryset.filter(material_category=material_category)
|
||||
queryset = queryset.filter(material_category__icontains=material_category)
|
||||
|
||||
# 支持按材料子类过滤
|
||||
material_subcategory = self.request.query_params.get('material_subcategory')
|
||||
|
|
@ -200,6 +201,52 @@ class MaterialViewSet(ModelViewSet):
|
|||
if advantage:
|
||||
queryset = queryset.filter(advantage__contains=[advantage])
|
||||
|
||||
# 阶段
|
||||
stage = self.request.query_params.get('stage')
|
||||
if stage:
|
||||
queryset = queryset.filter(stage=stage)
|
||||
|
||||
# 重要等级
|
||||
importance_level = self.request.query_params.get('importance_level')
|
||||
if importance_level:
|
||||
queryset = queryset.filter(importance_level=importance_level)
|
||||
|
||||
# 供应商(显式 id 过滤)
|
||||
factory = self.request.query_params.get('factory')
|
||||
if factory:
|
||||
queryset = queryset.filter(factory_id=factory)
|
||||
|
||||
# 合作模式
|
||||
cooperation_mode = self.request.query_params.get('factory__cooperation_mode')
|
||||
if cooperation_mode:
|
||||
queryset = queryset.filter(factory__cooperation_mode=cooperation_mode)
|
||||
|
||||
# 落地项目(模糊)
|
||||
landing_project = self.request.query_params.get('landing_project')
|
||||
if landing_project:
|
||||
queryset = queryset.filter(landing_project__icontains=landing_project)
|
||||
|
||||
# 成本比较区间
|
||||
cost_gte = self.request.query_params.get('cost_compare__gte')
|
||||
if cost_gte not in (None, ''):
|
||||
queryset = queryset.filter(cost_compare__gte=cost_gte)
|
||||
cost_lte = self.request.query_params.get('cost_compare__lte')
|
||||
if cost_lte not in (None, ''):
|
||||
queryset = queryset.filter(cost_compare__lte=cost_lte)
|
||||
|
||||
# 综合评分下限
|
||||
score_gte = self.request.query_params.get('score_level__gte')
|
||||
if score_gte not in (None, ''):
|
||||
queryset = queryset.filter(score_level__gte=score_gte)
|
||||
|
||||
# 对接人 / 经办人
|
||||
contact_person = self.request.query_params.get('contact_person')
|
||||
if contact_person:
|
||||
queryset = queryset.filter(contact_person__icontains=contact_person)
|
||||
handler = self.request.query_params.get('handler')
|
||||
if handler:
|
||||
queryset = queryset.filter(handler__icontains=handler)
|
||||
|
||||
return queryset
|
||||
|
||||
def get_serializer_class(self):
|
||||
|
|
@ -333,6 +380,7 @@ class MaterialViewSet(ModelViewSet):
|
|||
'application_scene': Material.APPLICATION_SCENE_CHOICES,
|
||||
'star_level': Material.STAR_LEVEL_CHOICES,
|
||||
'status': Material.STATUS_CHOICES,
|
||||
'cooperation_mode': COOPERATION_MODE_CHOICES,
|
||||
})
|
||||
|
||||
@action(detail=False, methods=['get'], url_path='template')
|
||||
|
|
|
|||
Loading…
Reference in New Issue