You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django独立ProductUpload视图上传失败,如何整合上传逻辑?

如何将含多对多字段的产品上传逻辑整合到独立视图中?

问题背景

已有定义了多对多category字段的Product模型:

class Product(models.Model):
    name = models.CharField(max_length=255, blank=False)
    category = models.ManyToManyField(ProductCategory)
    thumbnail_image = models.ImageField(null=True, blank=True)
    description = models.TextField(null=False, blank=False)
    price = models.DecimalField(max_digits=20, decimal_places=2, null=False, blank=False)
    stock = models.IntegerField(default=0)
    tag = models.CharField(max_length=255, null=True, blank=True)
    date = models.DateTimeField(auto_now=True)
    enable = models.BooleanField(default=True)

尝试通过独立的ProductUpload视图处理产品上传时失败,但使用带POST方法的ProductList视图(依赖序列化器)可正常上传。需修复ProductUpload视图的上传逻辑。

原视图失败原因

原ProductUpload视图存在以下问题:

  • 字段名拼写错误:thumbnamil_image应为thumbnail_image,导致文件无法正确获取
  • 未做数据类型转换:前端传递的price(字符串)、enable(字符串"true"/"false")直接赋值给对应模型字段会触发类型错误
  • 多对多关联处理错误:product.category.add()需传入模型对象或主键整数,而request.POST.getlist('category')返回的是字符串列表,直接传递会报错
  • 缺少数据验证:手动创建实例时未触发模型内置验证,易存入无效数据

解决方案

方案一:复用已有序列化器(推荐)

直接复用能正确处理多对多关联和文件上传的ProductSerializer,这是最简洁且不易出错的方式:

from rest_framework import status

@api_view(['POST'])
def ProductUpload(request):
    serializer = ProductSerializer(data=request.data, many=False)
    if serializer.is_valid():
        serializer.save()
        return Response({'message': 'success'}, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

方案二:手动处理模型创建与关联(不推荐,仅作演示)

若需手动实现逻辑,需修复上述问题,代码如下:

from decimal import Decimal
from django.core.exceptions import ValidationError
from rest_framework import status

@api_view(['POST'])
def ProductUpload(request):
    try:
        # 正确获取上传文件
        img = request.FILES.get('thumbnail_image')
        data = request.data
        
        # 数据类型转换与必填字段校验
        product_data = {
            'name': data['name'],
            'thumbnail_image': img,
            'description': data['description'],
            'price': Decimal(data['price']),
            'stock': int(data['stock']),
            'tag': data.get('tag'),
            # 处理布尔值的字符串/布尔输入
            'enable': data['enable'].lower() == 'true' if isinstance(data['enable'], str) else bool(data['enable'])
        }
        
        # 触发模型验证,避免无效数据存入
        product = Product(**product_data)
        product.full_clean()
        product.save()
        
        # 处理多对多关联:过滤有效分类后添加
        category_ids = request.data.getlist('category')
        valid_categories = ProductCategory.objects.filter(id__in=category_ids)
        product.category.add(*valid_categories)
        
        return Response({'message': 'success'}, status=status.HTTP_201_CREATED)
    
    except KeyError as e:
        return Response({'error': f'缺少必填字段: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)
    except (ValidationError, ValueError) as e:
        return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)

内容的提问来源于stack exchange,提问作者user19059958

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:31:35