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

如何在Django中通过原生SQL将InMemoryUploadedFile存入SQLite数据库

问题:Django图片上传数据库报错

已在settings.py中配置MEDIA_ROOT与MEDIA_URL,但上传图片时出现报错:

can only concatenate str (not "InMemoryUploadedFile") to str
原因是直接使用原生SQL无法处理InMemoryUploadedFile类型的文件数据。


views.py 相关函数

@login_required
def course_add(request):
    if request.method=='POST':
        bullyname=request.POST['bullyname']
        contact=request.POST['contact']
        email=request.POST['email']
        facebookLink=request.POST['facebookLink']
        instaLink=request.POST['instaLink']
        linkedinLink=request.POST['linkedinLink']
        snapLink=request.POST['snapLink']
    
        file=request.FILES.get('myfile')
      
        # 数据库连接
        db_cursor=connections['default'].cursor()
    
        # 插入数据的SQL语句
        db_cursor.execute("INSERT INTO University_complains (name,contact,email,facebookid,instaid,linkedinid,snapid,prove) VALUES('"+bullyname+"','"+contact+"','"+email+"','"+facebookLink+"','"+instaLink+"','"+linkedinLink+"','"+snapLink+"','"+file+"')")
    
     return render(request, 'course_add.html')

models.py 相关类

class Complains(models.Model):
    name=models.CharField(max_length=50,null=False,verbose_name="Bull Name",primary_key=True)
    contact=models.CharField(max_length=15,null=False,verbose_name="Contact No")
    email=models.CharField(max_length=30,verbose_name="E mail")
    facebookid=models.CharField(max_length=100,verbose_name="Facebook ID")
    instaid=models.CharField(max_length=100,verbose_name="Instagram ID")
    linkedinid=models.CharField(max_length=100,verbose_name="Linkedin ID")
    snapid=models.CharField(max_length=100,verbose_name="Snapchat ID")
    prove=models.ImageField(upload_to='proves/')

settings.py 媒体配置

STATIC_URL = 'static/'
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR,'media')

解决方案

1. 优先使用Django ORM处理(推荐)

Django的ImageField已经封装了文件存储逻辑,用ORM创建对象可自动完成文件保存和数据库路径存储,完全规避类型问题:
修改views.py中的函数:

@login_required
def course_add(request):
    if request.method=='POST':
        # 直接用ORM实例化模型并保存
        complain = Complains(
            name=request.POST['bullyname'],
            contact=request.POST['contact'],
            email=request.POST['email'],
            facebookid=request.POST['facebookLink'],
            instaid=request.POST['instaLink'],
            linkedinid=request.POST['linkedinLink'],
            snapid=request.POST['snapLink'],
            prove=request.FILES.get('myfile')
        )
        complain.save()
    return render(request, 'course_add.html')

ORM会自动将文件保存到MEDIA_ROOT/proves/目录,同时把文件相对路径存入数据库,无需手动处理类型转换。

2. 确保前端表单配置正确

前端表单必须添加enctype="multipart/form-data"属性,否则无法正确接收文件:

<form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <!-- 其他表单字段 -->
    <input type="file" name="myfile">
    <button type="submit">提交</button>
</form>

3. 若坚持使用原生SQL(不推荐)

如果一定要用原生SQL,需手动将文件保存到本地目录,再把路径字符串插入数据库:

import os
from django.conf import settings

@login_required
def course_add(request):
    if request.method=='POST':
        bullyname=request.POST['bullyname']
        contact=request.POST['contact']
        email=request.POST['email']
        facebookLink=request.POST['facebookLink']
        instaLink=request.POST['instaLink']
        linkedinLink=request.POST['linkedinLink']
        snapLink=request.POST['snapLink']
    
        file=request.FILES.get('myfile')
        if file:
            # 构建文件保存路径
            file_path = os.path.join('proves/', file.name)
            full_save_path = os.path.join(settings.MEDIA_ROOT, file_path)
            # 写入文件到本地
            with open(full_save_path, 'wb+') as destination:
                for chunk in file.chunks():
                    destination.write(chunk)
            # 用参数化SQL插入路径(避免SQL注入)
            db_cursor=connections['default'].cursor()
            db_cursor.execute("""
                INSERT INTO University_complains 
                (name,contact,email,facebookid,instaid,linkedinid,snapid,prove) 
                VALUES(%s,%s,%s,%s,%s,%s,%s,%s)
            """, (bullyname, contact, email, facebookLink, instaLink, linkedinLink, snapLink, file_path))
    return render(request, 'course_add.html')

注意:这种方式需要手动处理文件重名、权限、异常等问题,安全性和便捷性远不如ORM。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 02:01:14