在drf中,序列化器已经对django的上传图片与写入文件进行了封装,更加简单。前端传递的格式必须是content_type=multipart/form-data
一、定义模型类:
- 图片字段使用ImageField
- 前端传递过来的图片接收之后需要对图片名做处理,当业务场景很大的时候,有可能会出现图片名重复的情况,后存入的数据库的图片会把先前同名的图片文件给覆盖掉,所以必须做处理。使用uuid来进行,返回文件名和相对路径,uuid唯一标识码,重名的概率极低。处理放在字段的upload中
需要特别注意的是:对文件名的处理在字段这里设置之后,不能同时在views.py文件中对这一字段进行重复设置,如果两个都设置了程序会报错:images:传入的内容不是文件,请检查编码格式
import uuid#提取出公共的方法evaluation_directory_path获取图片后缀# 使用uuid创建唯一的图片名,并保存的路径和文件名一并返回def evaluation_directory_path(product_id, filename):ext = filename.split('.')[-1]filename = '{}.{}'.format(uuid.uuid4().hex[:10], ext)return os.path.join("evaluations", filename)class ProductEvaluationImage(models.Model):evaluation = models.ForeignKey(ProductEvaluation, related_name="evaluation_images", on_delete=models.CASCADE, verbose_name="关联评论")images = models.FileField(null=True, blank=True, upload_to=evaluation_directory_path, verbose_name="商品评价图片")class Meta:verbose_name = "商品评价关联图"verbose_name_plural = verbose_namedef __str__(self):return self.evaluation.detail_content
二、视图中处理
- 图片文件的处理需要用到解析器,所以需要从drf中导入对应的解析器
- python3中获取post过来的图片文件是需要用到request.FILES.getlist(key)的方式来获取,必须是getlist
- 对图片图片列表进行遍历,创建序列化器,分别取出图片写入文件和添加到数据库字段中,序列化器会自动处理,不需要在自己编写程序写入文件。数据库字段只是写入文件的路径,二进制文件中存入的才是图片的内容 ```python from rest_framework.parsers import JSONParser, MultiPartParser
class ProductEvaluationImageView(GenericAPIView): queryset = ProductEvaluationImage.objects.all() serializer_class = ProdcutEvaluationImageSerializers parser_classes = [JSONParser, MultiPartParser]
def post(self, request):data = request.datafiles = request.FILES.getlist('images')product_id = request.data['product']for file in files:serializer = self.get_serializer(data={"images": file, "evaluation": data["evaluation"]})serializer.is_valid(raise_exception=True)serializer.save()return Response("获取成功", status=200)
<a name="bFCHF"></a>### 三、序列化器```pythonclass ProdcutEvaluationImageSerializers(serializers.ModelSerializer):''' 用户评论关联图片序列化器 '''images = serializers.ImageField(max_length=None, use_url=True, allow_null=True, required=False)class Meta:model = ProductEvaluationImagefields = "__all__"
