1
0
forked from erp-dev/erp
Files
erpnew/api_man/serializers.py

162 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from rest_framework import serializers
from basic_info import models as basic_models
import logging
logger = logging.getLogger(__name__)
class BaseSerializer(serializers.ModelSerializer):
merchant = serializers.PrimaryKeyRelatedField(
queryset=basic_models.Merchant.objects.all(),
required=False # 创建时由视图层设置
)
def to_representation(self, instance):
# 检查是否有 request context以及是否需要进行权限验证
request = self.context.get('request')
if request and hasattr(request, 'user') and hasattr(request.user, 'employee'):
try:
merchant = request.user.employee.merchant
if instance.merchant != merchant:
# 数据保护手段
logger.warning(f"用户 {request.user.username} 无权限访问对象 {type(instance).__name__} {instance.id}")
raise PermissionError("无权限访问该对象")
except AttributeError as e:
# 用户没有 employee 属性
logger.warning(f"用户权限验证失败: {str(e)}")
raise PermissionError("无权限访问该对象")
result = super().to_representation(instance)
if self.context.get('expand_merchant', False):
result['merchant'] = {
'id': instance.merchant.id,
'name': instance.merchant.name
}
return result
class QuickInputSerializer(serializers.ModelSerializer):
class Meta:
model = basic_models.QuickInput
fields = ['id', 'name', 'value', 'group']
class ProductCategorySerializer(BaseSerializer):
class Meta:
model = basic_models.ProductCategory
fields = '__all__'
class ProductSerializer(BaseSerializer):
# 图片字段:读取时返回完整 URL写入时接受文件上传或 URL
image = serializers.ImageField(required=False, allow_null=True)
image_url = serializers.SerializerMethodField(read_only=True)
class Meta:
model = basic_models.Product
fields = '__all__'
def get_image_url(self, obj):
"""
获取图片的完整 URL
返回:
- 如果有图片:返回完整 URL七牛云 CDN 地址)
- 如果没有图片:返回 None
"""
if obj.image:
request = self.context.get('request')
if request:
# 使用 request.build_absolute_uri 构建完整 URL
return request.build_absolute_uri(obj.image.url)
else:
# 没有 request context 时,返回相对 URL
# 七牛云存储会自动返回完整 URL
return obj.image.url
return None
def to_representation(self, instance):
result = super().to_representation(instance)
result['category'] = {
'id': instance.category.id,
'name': instance.category.name
}
# 如果使用七牛云image 字段已经是完整 URL添加额外的 image_url 方便前端使用
# 前端可以使用 image 或 image_url两者内容相同
return result
class WareHouseSerializer(BaseSerializer):
class Meta:
model = basic_models.WareHouse
fields = '__all__'
class SupplierSerializer(BaseSerializer):
class Meta:
model = basic_models.Supplier
fields = '__all__'
class EmployeeSerializer(BaseSerializer):
job_type = serializers.CharField(read_only=True)
class Meta:
model = basic_models.Employee
fields = '__all__'
class EmployeeTypeSerializer(BaseSerializer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 移除 unique_together 验证器中对 merchant 的要求
# 因为 merchant 会在 perform_create 中自动设置
for validator in self.validators:
if hasattr(validator, 'fields') and 'merchant' in validator.fields:
validator.fields = tuple(f for f in validator.fields if f != 'merchant')
class Meta:
model = basic_models.EmployeeType
fields = '__all__'
class CustomerSerializer(BaseSerializer):
created_by = serializers.PrimaryKeyRelatedField(
queryset=basic_models.Employee.objects.all(),
required=False,
)
class Meta:
model = basic_models.Customer
fields = '__all__'
class VehicleTypeSerializer(BaseSerializer):
class Meta:
model = basic_models.VehicleType
fields = '__all__'
class BankAccountSerializer(BaseSerializer):
class Meta:
model = basic_models.BankAccount
fields = '__all__'
class DeviceInfoSerializer(BaseSerializer):
class Meta:
model = basic_models.DeviceInfo
fields = '__all__'
class VehicleTransportRecordSerializer(BaseSerializer):
vehicle_type_name = serializers.CharField(source='vehicle_type.name', read_only=True)
class Meta:
model = basic_models.VehicleTransportRecord
fields = '__all__'
depth = 1 # 展开外键关系