Django后台创建对象时,基于字段值生成二维码遇文件不存在错误
解决Django生成二维码时的目录不存在问题
问题根源
原代码直接使用相对路径保存二维码文件,该路径并非Django配置的媒体文件根目录,且未提前创建保存目录,导致报错No such file or directory。
修复方案
1. 配置媒体文件(settings.py)
确保项目已正确配置媒体文件路径:
MEDIA_ROOT = BASE_DIR / 'media' MEDIA_URL = '/media/'
2. 配置开发环境媒体访问(urls.py)
添加媒体文件的URL映射,方便开发时访问:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 你的其他URL配置 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
3. 修改模型的save方法
改用Django规范的文件处理方式,自动创建目录并保存二维码:
import os import qrcode from django.conf import settings from django.core.files.base import ContentFile class People(models.Model): name = models.CharField(max_length=500, unique=True) qr_code = models.ImageField(upload_to="img/qr_codes/", verbose_name="QR-code", null=True) def save(self, *args, **kwargs): # 生成二维码实例 qr = qrcode.QRCode( version=2, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=1 ) qr.add_data(self.name) qr.make(fit=True) img = qr.make_image() # 确保保存目录存在,不存在则自动创建 qr_save_dir = os.path.join(settings.MEDIA_ROOT, "img/qr_codes") os.makedirs(qr_save_dir, exist_ok=True) # 将二维码转为字节流,通过ContentFile保存到ImageField img_byte_data = img.tobytes() filename = f"{self.name}.png" # save=False避免递归触发save方法 self.qr_code.save(filename, ContentFile(img_byte_data), save=False) # 调用父类保存方法完成对象存储 super().save(*args, **kwargs)
关键改进点
- 基于
MEDIA_ROOT构建真实保存路径,确保文件存放在Django指定的媒体目录下 - 使用
os.makedirs(..., exist_ok=True)自动创建缺失的目录 - 采用
ContentFile直接将图片字节流写入ImageField,无需手动操作磁盘文件,适配Django的文件存储机制 - 添加
save=False防止递归调用save方法
内容的提问来源于stack exchange,提问作者Dig Big
相关产品推荐
相关产品推荐

