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

Django中如何将PDF/图片存入数据库而非文件存储?含存取方案

Django直接将文件存入数据库的实现方案

1. 模型字段类型选择

用BinaryField存储文件的二进制核心数据,同时搭配辅助字段记录文件元信息:

  • CharField:存储文件名(建议设max_length=255)
  • CharField:存储文件MIME类型(比如image/jpeg、application/pdf,设max_length=100)
  • 可选IntegerField:存储文件字节大小

示例模型代码:

from django.db import models

class StoredFile(models.Model):
    file_data = models.BinaryField()
    filename = models.CharField(max_length=255)
    content_type = models.CharField(max_length=100)
    file_size = models.IntegerField(null=True, blank=True)

2. 业务信息与文件分表存储

拆分两个模型,通过外键建立关联,实现业务数据和文件数据分离:

  • 一个模型存储业务主数据(比如订单、记录等)
  • 一个模型专门存储文件数据,外键指向业务模型,支持一条业务数据对应多个文件

示例代码:

# 业务信息表
class BusinessRecord(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

# 文件存储表,关联业务表
class StoredFile(models.Model):
    business_record = models.ForeignKey(
        BusinessRecord, 
        on_delete=models.CASCADE, 
        related_name='attached_files'
    )
    file_data = models.BinaryField()
    filename = models.CharField(max_length=255)
    content_type = models.CharField(max_length=100)
    file_size = models.IntegerField(null=True, blank=True)

related_name='attached_files'方便后续从业务条目反向查询关联的所有文件。

3. 文件检索与查看

检索文件

通过关联关系查询,比如获取某条业务记录的所有文件:

# 获取id=1的业务记录
record = BusinessRecord.objects.get(id=1)
# 拿到关联的所有文件
files = record.attached_files.all()

也可以按文件类型、文件名筛选:

# 筛选所有PDF文件
pdf_files = StoredFile.objects.filter(content_type='application/pdf')
# 筛选所有图片文件
image_files = StoredFile.objects.filter(content_type__startswith='image/')

查看/下载文件

在视图中读取二进制数据,返回HttpResponse并设置正确响应头,支持在线预览或下载:

from django.http import HttpResponse

def view_file(request, file_id):
    stored_file = StoredFile.objects.get(id=file_id)
    # 构造响应
    response = HttpResponse(stored_file.file_data, content_type=stored_file.content_type)
    # 若要下载,把inline改成attachment
    response['Content-Disposition'] = f'inline; filename="{stored_file.filename}"'
    return response

在urls.py配置对应路由:

path('files/<int:file_id>/', view_file, name='view_file'),

4. 模板表单上传文件并关联业务数据

第一步:定义表单类

包含业务字段和文件上传字段,注意表单需支持多部分数据传输:

from django import forms
from .models import BusinessRecord, StoredFile

class BusinessFileForm(forms.Form):
    title = forms.CharField(max_length=200)
    content = forms.CharField(widget=forms.Textarea)
    # 支持多文件上传改用MultipleFileField
    file = forms.FileField()

第二步:视图处理上传逻辑

def upload_with_file(request):
    if request.method == 'POST':
        form = BusinessFileForm(request.POST, request.FILES)
        if form.is_valid():
            # 先保存业务记录
            record = BusinessRecord.objects.create(
                title=form.cleaned_data['title'],
                content=form.cleaned_data['content']
            )
            # 处理上传的文件
            uploaded_file = request.FILES['file']
            # 读取文件二进制内容
            file_data = uploaded_file.read()
            # 保存到文件表并关联业务记录
            StoredFile.objects.create(
                business_record=record,
                file_data=file_data,
                filename=uploaded_file.name,
                content_type=uploaded_file.content_type,
                file_size=uploaded_file.size
            )
            return HttpResponse('上传成功')
    else:
        form = BusinessFileForm()
    return render(request, 'upload.html', {'form': form})

第三步:模板页面

确保表单设置enctype="multipart/form-data"属性:

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">提交</button>
</form>

若需多文件上传,将表单字段改为MultipleFileField,视图中用request.FILES.getlist('file')循环处理每个文件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 08:47:26