下面是“Django实现上传图片功能”的完整攻略。
步骤一:创建Django工程和应用
首先,我们需要创建一个Django工程和一个应用。使用以下命令可以快速创建:
django-admin startproject myproject
cd myproject
python manage.py startapp myapp
其中 myproject 和 myapp 可以根据个人需求进行命名。
步骤二:配置Django设置
在 myproject/settings.py 文件中添加以下内容:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
其中 MEDIA_ROOT
是指定上传文件保存的目录,MEDIA_URL
是指在网站中访问上传文件的URL。
并在 myproject/urls.py 文件中添加以下配置:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
这个配置是用来告诉 Django 在访问 MEDIA_URL
时,使用 MEDIA_ROOT
目录下的文件进行响应。
步骤三:创建上传表单
在 myapp 目录下创建 forms.py 文件,并添加以下代码:
from django import forms
class UploadFileForm(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField()
这个表单包含了一个文件上传字段和一个字符串类型的标题字段。
步骤四:编写视图函数
在 myapp/views.py 文件中添加以下代码:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from .forms import UploadFileForm
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
title = form.cleaned_data['title']
file = form.cleaned_data['file']
with open(settings.MEDIA_ROOT + '/' + file.name, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
# 保存文件之后,返回到上传成功页面
return HttpResponseRedirect(reverse('success'))
else:
form = UploadFileForm()
return render(request, 'upload.html', {'form': form})
这个视图函数处理上传文件的逻辑。如果请求方法是 POST
,就会读取表单数据并将上传的文件保存到 MEDIA_ROOT
目录下,并且重定向到成功页面;否则就会返回一个新的表单页面。
步骤五:创建模板
在 myapp/templates 目录下创建一个名为 upload.html
的模板文件,并添加以下内容:
{% extends "base.html" %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">上传</button>
</form>
{% endblock %}
这个模板包含一个文件上传表单和一个提交按钮。
在 myapp/templates 目录下创建一个名为 success.html
的模板文件,并添加以下内容:
{% extends "base.html" %}
{% block content %}
<h2>上传成功!</h2>
{% endblock %}
这个模板用来展示上传成功的提示信息。
步骤六:创建基本模板
在 myapp/templates 目录下创建一个名为 base.html
的模板文件,并添加以下内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
这个模板定义了一个基本的HTML框架,其他页面可以通过继承这个模板来快速构建。
步骤七:创建路由
在 myapp 目录下创建一个名为 urls.py
的文件,并添加以下内容:
from django.urls import path
from .views import upload_file
urlpatterns = [
path('upload/', upload_file, name='upload'),
path('success/', success, name='success'),
]
这个路由配置定义了两个URL规则。/upload/
路径用于显示上传文件的表单,/success/
路径用于上传成功后的提示信息。
示例一:上传图片并显示
在 myapp/views.py 文件中添加以下代码:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from .forms import UploadFileForm
from .models import Image
def upload_image(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
title = form.cleaned_data['title']
file = form.cleaned_data['file']
image = Image.objects.create(
title=title,
image=file
)
# 保存图片之后,返回到上传成功页面
return HttpResponseRedirect(reverse('success'))
else:
form = UploadFileForm()
return render(request, 'upload.html', {'form': form})
def image_list(request):
images = Image.objects.all()
return render(request, 'image_list.html', {'images': images})
这个代码新增了两个视图函数。upload_image
用来处理图片的上传,将上传的图片保存到 Image
模型中,并且在上传成功之后重定向到成功页面。image_list
用来展示上传的所有图片。
在 myapp/models.py 文件中添加以下代码:
from django.db import models
class Image(models.Model):
title = models.CharField(max_length=50)
image = models.ImageField(upload_to='images/')
def __str__(self):
return self.title
这个模型定义了一个上传图片的数据模型,包含 title
字段和 image
字段,其中 image
字段是 ImageField
类型,用于保存上传的图片。
在 myapp/templates 目录下创建一个名为 image_list.html
的模板文件,并添加以下内容:
{% extends "base.html" %}
{% block title %}
图片列表
{% endblock %}
{% block content %}
<h2>图片列表</h2>
{% for image in images %}
<div>
<h3>{{ image.title }}</h3>
<img src="{{ image.image.url }}" width="300" />
</div>
{% endfor %}
{% endblock %}
这个模板用于展示上传的图片列表,包含每张图片的标题和图片缩略图(使用 img
标签并设置宽度为 300px)。
在 myapp/urls.py 文件中添加以下内容:
from django.urls import path
from .views import upload_image, image_list
urlpatterns = [
path('', image_list, name='image_list'),
path('upload/', upload_image, name='upload_image'),
path('success/', success, name='success'),
]
这个路由配置将 /
路径定义为 image_list
视图,用于展示上传的所有图片。/upload/
路径依然用于上传图片,后续可以在图片列表页面。
示例二:批量上传图片并打包压缩文件提供下载
在 myapp/templates 目录下创建一个名为 upload_batch.html
的模板文件,并添加以下内容:
{% extends "base.html" %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">上传</button>
</form>
{% endblock %}
这个模板包含一个批量文件上传表单和一个提交按钮。
在 myapp/views.py 文件中添加以下代码:
import os
import zipfile
from django.conf import settings
from django.http import HttpResponse, JsonResponse, FileResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def upload_batch(request):
if request.method == 'GET':
return render(request, 'upload_batch.html', {'form': UploadFileForm()})
else:
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
uploaded_files = []
for file in request.FILES.getlist('file'):
uploaded_file_path = os.path.join(settings.MEDIA_ROOT, file.name)
with open(uploaded_file_path, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
uploaded_files.append(uploaded_file_path)
# 压缩文件并提供下载
files_zip_path = os.path.join(settings.MEDIA_ROOT, 'files.zip')
with zipfile.ZipFile(files_zip_path, 'w') as zipped_file:
for uploaded_file_path in uploaded_files:
zipped_file.write(uploaded_file_path)
response = FileResponse(open(files_zip_path, 'rb'))
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename={}'.format(os.path.basename(files_zip_path))
return response
return JsonResponse({'status': 'error', 'msg': '上传文件格式不正确,支持多个txt、jpg、png文件'})
def success(request):
return render(request, 'success.html', {})
这个视图函数处理批量上传文件的逻辑,在上传成功之后将上传的所有文件打包压缩成zip文件后提供下载。
在 myapp/urls.py 文件中添加一条路由:
from django.urls import path
from .views import upload_batch
urlpatterns = [
path('upload_batch/', upload_batch, name='upload_batch'),
]
这个路由用于处理文件上传页面以及直接文件下载。访问 /upload_batch/ 将提示上传文件界面,上传完成后会下载文件。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django实现上传图片功能 - Python技术站