如何在Django REST Framework中接收多Base64图片创建帖子
Django接收Base64多张图片并保存到媒体系统的实现方案
1. 基础配置检查
先确保Django媒体目录配置正确,在settings.py中添加:
MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
同时在项目根urls.py中配置开发环境的媒体路由:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 你的其他路由配置 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
2. 模型调整(假设已有Post关联图片的结构)
如果还没有图片关联模型,创建PostImage与Post关联:
from django.db import models class Post(models.Model): title = models.CharField(max_length=255) content = models.TextField() created_at = models.DateTimeField(auto_now_add=True) class PostImage(models.Model): post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='images') image = models.ImageField(upload_to='post_images/%Y/%m/%d/') # 按日期分目录存储,避免文件名冲突
3. 编写Base64图片解码工具
新建utils.py文件,实现Base64字符串转Django可存储的文件对象:
import base64 import io from django.core.files.base import ContentFile from PIL import Image def decode_base64_image(base64_str): # 拆分Base64头和数据部分,兼容带/不带头部的情况 if 'base64,' in base64_str: header, data = base64_str.split('base64,', 1) ext = header.split('/')[1].split(';')[0] else: data = base64_str ext = 'jpeg' # 默认格式,可根据实际调整 # 解码并转换为ContentFile decoded_data = base64.b64decode(data) image_file = io.BytesIO(decoded_data) # 可选:用PIL处理图片(压缩、格式转换等) img = Image.open(image_file) buffer = io.BytesIO() img.save(buffer, format=ext.upper()) buffer.seek(0) return ContentFile(buffer.read(), name=f"post_img_{hash(data)}.{ext}") # 用哈希值做文件名避免重复
4. 自定义序列化器处理图片数据
编写嵌套序列化器,接收Base64字符串并自动转换为图片文件:
from rest_framework import serializers from .models import Post, PostImage from .utils import decode_base64_image class PostImageSerializer(serializers.ModelSerializer): image_base64 = serializers.CharField(write_only=True) # 仅用于接收前端传来的Base64字符串 class Meta: model = PostImage fields = ['image_base64'] class PostSerializer(serializers.ModelSerializer): images = PostImageSerializer(many=True, write_only=True) class Meta: model = Post fields = ['title', 'content', 'images'] def create(self, validated_data): # 提取图片数据,创建Post实例 images_data = validated_data.pop('images') post = Post.objects.create(**validated_data) # 批量处理并保存图片 for img_data in images_data: img_file = decode_base64_image(img_data['image_base64']) PostImage.objects.create(post=post, image=img_file) return post
5. 编写视图处理请求
用通用视图快速实现创建接口:
from rest_framework import generics from .models import Post from .serializers import PostSerializer class PostCreateView(generics.CreateAPIView): queryset = Post.objects.all() serializer_class = PostSerializer
示例请求数据格式
前端需按如下JSON结构发送请求:
{ "title": "旅行打卡", "content": "今天去了海边", "images": [ {"image_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAAAAAAD..."}, {"image_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QAAA..."} ] }
后续迁移到S3的注意事项
无需改动业务代码,仅修改settings.py配置即可切换到S3存储:
# 先安装依赖:pip install boto3 django-storages AWS_ACCESS_KEY_ID = '你的AWS密钥ID' AWS_SECRET_ACCESS_KEY = '你的AWS密钥' AWS_STORAGE_BUCKET_NAME = '存储桶名称' AWS_S3_REGION_NAME = '存储桶区域,如us-east-1' AWS_S3_FILE_OVERWRITE = False AWS_DEFAULT_ACL = None AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com' # 替换默认文件存储后端 DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
内容的提问来源于stack exchange,提问作者Aremu Oluwaseyi Festus
相关产品推荐
相关产品推荐

