当前位置: 首页 > news >正文

在Django中把Base64字符串保存为ImageField

在数据model中使用ImageField来管理avatar。

class User(models.Model):AVATAR_COLORS = (('#212736', 'Black'),('#2161FD', 'Blue'),('#36B37E', 'Green'),('#F5121D', 'Red'),('#FE802F', 'Orange'),('#9254DE', 'Purple'),('#EB2F96', 'Magenta'),)def generate_filename(self, filename):url = "avatar-{}-{}".format(self.user.username, filename)return urlavatar = models.ImageField(upload_to=generate_filename, verbose_name='头像', null=True, blank=True)avatar_color = models.CharField(verbose_name='头像颜色', choices=AVATAR_COLORS, max_length=10, blank=True, null=True)#这里省略其他字段

前端avatar字段传输的是Base64字符串,Django后端将其转换为ContentFile后进行save。

首先,确保你已经安装了Pillow库,它是Django中处理图像的常用库。

import base64
import binascii
import imghdr
import io
import uuidfrom django.core.exceptions import ValidationError
from django.core.files.base import ContentFileclass Base64ToImageFile(object):"""A django-rest-framework field for handling image-uploads through raw post data.It uses base64 for en-/decoding the contents of the file."""ALLOWED_TYPES = ("jpeg","jpg","png","gif")EMPTY_VALUES = (None, '', [], (), {})INVALID_FILE_MESSAGE = "Please upload a valid image."INVALID_TYPE_MESSAGE = "The type of the image couldn't be determined."def to_file(self, base64_data):# Check if this is a base64 stringif base64_data in self.EMPTY_VALUES:return Noneif isinstance(base64_data, str):# Strip base64 header.if ';base64,' in base64_data:header, base64_data = base64_data.split(';base64,')# Try to decode the file. Return validation error if it fails.try:decoded_file = base64.b64decode(base64_data)except (TypeError, binascii.Error, ValueError):raise ValidationError(self.INVALID_FILE_MESSAGE)# Generate file name:file_name = self.get_file_name(decoded_file)# Get the file name extension:file_extension = self.get_file_extension(file_name, decoded_file)if file_extension not in self.ALLOWED_TYPES:raise ValidationError(self.INVALID_TYPE_MESSAGE)complete_file_name = file_name + "." + file_extensiondata = ContentFile(decoded_file, name=complete_file_name)return dataraise ValidationError('Invalid type. This is not an base64 string: {}'.format(type(base64_data)))def get_file_name(self, decoded_file):return str(uuid.uuid4())def get_file_extension(self, filename, decoded_file):try:from PIL import Imageexcept ImportError:raise ImportError("Pillow is not installed.")extension = imghdr.what(filename, decoded_file)# Try with PIL as fallback if format not detected due# to bug in imghdr https://bugs.python.org/issue16512if extension is None:try:image = Image.open(io.BytesIO(decoded_file))except (OSError, IOError):raise ValidationError(self.INVALID_FILE_MESSAGE)extension = image.format.lower()extension = "jpg" if extension == "jpeg" else extensionreturn extensiondef base64_string_to_file(base64_string):return Base64ToImageFile().to_file(base64_string)

在创建用户过程中,给avatar字段赋值ContentFile类型

        avatar_file = base64_string_to_file(avatar_string)if avatar_file:request_data["avatar"] = avatar_fileelse:request_data.pop('avatar', None)serializer = UserCreateSerializer(data=request_data)if serializer.is_valid():user = serializer.save()

http://www.lryc.cn/news/573003.html

相关文章:

  • 掌握Python编程的核心能力,能快速读懂并上手项目开发。
  • HCIP-数据通信基础
  • 【网工】华为配置专题进阶篇④
  • 【Dify学习笔记】:RagFlow接入Dify基础教程
  • STM32:AS5600
  • Vuex(一) —— 集中式的状态管理仓库
  • 掌握Bash脚本编写:从服务启动脚本到语法精要
  • 防止应用调试分析IP被扫描加固实战教程
  • SAM2论文解读-既实现了视频的分割一切,又比图像的分割一切SAM更快更好
  • Springboot仿抖音app开发之Nacos 分布式服务与配置中心(进阶)
  • 文件夹美化工具推荐,打造个性化电脑界面
  • 音视频之H.264的可伸缩编码SVC
  • 【案例】性能优化在持续集成与持续交付中的应用
  • GO Gin Web框架面试题及参考答案
  • FPGA基础 -- Verilog 共享任务(task)和函数(function)
  • UE5错误 Linux离线状态下错误 请求失败libcurl错误:6无法解析主机名
  • 信任再造:跌倒检测算法如何让善意不再“自证”
  • Real-World Deep Local Motion Deblurring论文阅读
  • 结构体的嵌套问题
  • 【2025 年】软件体系结构考试试卷-期末考试
  • ABAP(2) 定义数据
  • 软件公司进军无人机领域的战略指南与生态合作全景-优雅草卓伊凡
  • Git 命令全景图:从 clone 到 merge 的完整流程解析
  • (双模第一期)从零打造蓝牙低功耗键盘——全流程详解与工具清单
  • window显示驱动开发—使用状态刷新回调函数
  • Vue2 day01
  • 20250620在Ubuntu20.04.6下编译KickPi的K7的Android14系统
  • java面试题02访问修饰符有哪些?区别是什么?
  • YOLOv11改进 | RCS-OSA与C3k2融合架构技术详解
  • React封装框架dvajs(状态管理+异步操作+数据订阅等)