在Django项目中实现图片上传功能,核心是通过ImageField字段定义模型属性,配合MEDIA_ROOT和MEDIA_URL完成上传文件的存储与访问配置,整体流程包含模型定义、配置设置、表单处理、视图逻辑编写几个环节。

基础环境准备
首先确保已经安装Pillow库,因为ImageField依赖该库处理图片文件,执行以下命令安装:
pip install Pillow
配置MEDIA相关参数
在项目的settings.py文件中添加以下配置,指定上传文件的存储根目录和访问URL:
# settings.py import os # 获取项目根目录路径 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 上传文件存储根目录,指向项目下的media文件夹 MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 上传文件的访问URL前缀 MEDIA_URL = '/media/'
同时需要在项目的urls.py中添加媒体文件的访问路由,否则上传后的图片无法通过URL访问:
# 项目主urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls')), # 替换为你的应用路由
]
# 开发环境下添加媒体文件访问路由
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)定义包含ImageField的模型
在应用的models.py中定义模型,使用ImageField字段存储图片:
# models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100, verbose_name="文章标题")
# upload_to指定图片在media目录下的子存储路径
image = models.ImageField(upload_to='article_images/', verbose_name="文章配图", null=True, blank=True)
content = models.TextField(verbose_name="文章内容")
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
def __str__(self):
return self.title执行迁移命令生成数据库表:
python manage.py makemigrations python manage.py migrate
编写图片上传表单
创建表单类,用于接收前端上传的图片数据:
# forms.py
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'image', 'content']
# 可以自定义表单控件的属性
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
'image': forms.FileInput(attrs={'class': 'form-control'}),
}编写视图处理逻辑
在视图中处理表单提交,完成图片上传和保存:
# views.py
from django.shortcuts import render, redirect
from .forms import ArticleForm
def article_create(request):
if request.method == 'POST':
form = ArticleForm(request.POST, request.FILES)
if form.is_valid():
# 保存表单数据,图片会自动保存到MEDIA_ROOT下upload_to指定的路径
form.save()
return redirect('article_list')
else:
form = ArticleForm()
return render(request, 'article_create.html', {'form': form})前端模板编写
创建对应的模板文件,注意表单需要添加enctype="multipart/form-data"属性才能上传文件:
<!-- article_create.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>发布文章</title>
</head>
<body>
<h2>发布新文章</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">提交</button>
</form>
</body>
</html>自定义图片保存路径
如果需要更灵活的保存路径,可以给upload_to传递一个可调用对象:
# models.py
import os
import time
from django.db import models
def custom_upload_path(instance, filename):
# 按日期生成子目录,避免文件名冲突
date_dir = time.strftime('%Y/%m/%d')
# 拼接完整路径
return os.path.join('article_images', date_dir, filename)
class Article(models.Model):
title = models.CharField(max_length=100)
# 使用自定义函数生成上传路径
image = models.ImageField(upload_to=custom_upload_path, null=True, blank=True)
content = models.TextField()常见问题说明
- 如果上传后提示文件不存在,检查MEDIA_ROOT路径是否正确,是否添加了媒体文件的URL路由
- 如果报Pillow相关错误,确认是否已经正确安装Pillow库
- 生产环境需要配置Web服务器(如Nginx)来处理媒体文件的访问,不要依赖Django的静态文件服务
- 可以在表单或模型中增加文件大小、格式的校验,避免上传非法文件
DjangoImageFieldMEDIA_ROOT文件上传模型字段修改时间:2026-06-12 09:45:16