35_文件上传_1
文件上传
实现步骤
配置URL
# from django.conf.urls import url, include
from django.urls import path, include
from django.contrib import admin
urlpatterns = [
# url(r'^admin/', admin.site.urls),
# url(r'^student/', include('student.urls')),
path('admin/', admin.site.urls),
path('student/', include("stuapp.urls")),
]
#coding=utf-8
# from django.conf.urls import url
from django.urls import path
from . import views
urlpatterns=[
# url(r'^$', views.Index.as_view()),
path('', views.Index.as_view()),
]
创建视图
# -*- coding: utf-8 -*-
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
# Create your views here.
from django.views import View
class Index(View):
def get(self,request):
return render(request,'index.html')
def post(self,request):
uname = request.POST.get('uname','')
photo = request.FILES.get('photo','')
import os
if not os.path.exists('static'):
os.makedirs('static')
with open(os.path.join(os.getcwd(),'static',photo.name),'wb') as fw:
#一次性读取文件
fw.write(photo.read())
return HttpResponse('上传成功!')
创建模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/student/" method="post" enctype="multipart/form-data">
{% csrf_token %}
用户名:<input type="text" name="uname"/><br/><br/>
头 像:<input type="file" name="photo"/><br/><br/>
    <input type="submit" value="注册"/>
</form>
</body>
</html>
随堂笔记:(原生的文件上传)
demo8/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('student/', include('stuapp1.urls')),
path('student2/', include('stuapp2.urls')),
]
demo8/settings.py
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
'stuapp1',
'stuapp2',
]
stuapp2/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('upload1/', views.upload1_view),
]
stuapp2/views.py
import os
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from demo8.settings import BASE_DIR
def upload1_view(request):
if request.method == "GET":
return render(request, "upload.html")
else:
# 获取请求参数
sname = request.POST.get('sname', '')
photo = request.FILES.get('photo', '')
# 返回一个上传文件对象 <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
# print(type(photo)) # type():查看变量类型
# 判断文件目录是否存在
m_path = os.path.join(BASE_DIR, 'media')
# print(m_path)
if not os.path.exists(m_path): # 如果路径不存在
# 创建当前目录
os.mkdir(m_path)
# 将图片写入目标文件夹
with open(os.path.join(m_path, photo.name), "wb") as fw:
# photo.read() # 一次性将文件读取到内存,比较消耗内存
# fw.write(photo.read())
# photo.chunks() 分块读取文件到内存
for c in photo.chunks():
fw.write(c)
return HttpResponse("上传成功!")
templates/upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/student2/upload1/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>姓名:<input name="sname"></p>
<p>图片:<input type="file" name="photo"></p>
<p>   <input type="submit"></p>
</form>
</body>
</html>
37_文件上传_3
Django文件上传
需求
- 完成学生信息注册操作
- 将学生信息入库
- 将上传文件存放至项目下media文件夹下
- 显示所有学生信息
创建模型类
from django.db import models
# Create your models here.
class Student(models.Model):
sname = models.CharField(max_length=30)
age = models.PositiveIntegerField()
photo = models.ImageField(upload_to="imgs/") # 这里用相对路径
# 上传文件 两种(ImageField(只传图片) / FileField(除了图片, txt文件、视频等都可以))
# 相当于 文件上传后存储的位置 = settings.py 文件中的 MEDIA_ROOT + upload_to
def __str__(self):
return self.sname
# class Meta: # 将表映射到数据库时命名为 ‘ t_stu ’用的
# db_table = 't_stu'
settings.py文件中文件上传相关设置
INSTALLED_APPS = [
...
'stuapp' # 增加注册应用
]
# 连接数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 增加,(也可不增,因为Django已经配置好了)
MEDIA_URL = '/media/'
# 增加
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
映射数据库表
#在终端中敲命令
python manage.py makemigrations stu
python manage.py migrate
配置URL
- demo9/urls.py
# coding=utf-8
# from django.conf.urls import url, include
# from django.contrib import admin
#
# from test13.settings import DEBUG, MEDIA_ROOT
#
# urlpatterns = [
# url(r'^admin/', admin.site.urls),
# url(r'^stu/', include('stu.urls')),
# ]
#
# 配置路由读取后台上传文件
# from django.views.static import serve
#
# if DEBUG:
# urlpatterns+=url(r'^media/(?P<path>.*)/$', serve, {"document_root": MEDIA_ROOT}),
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.static import serve
from demo9.settings import DEBUG, MEDIA_ROOT
urlpatterns = [
path('admin/', admin.site.urls),
path('student/', include("stuapp.urls")),
]
if DEBUG: # 开发调试模式
urlpatterns.append(re_path(r'^media/(?P<path>.*)', serve, {'document_root': MEDIA_ROOT}))
- stuapp/urls.py
# coding=utf-8
#
# from django.conf.urls import url
# import views
#
# urlpatterns=[
# url(r'^$',views.index_view),
# url(r'^upload1/$',views.upload1_view),
# url(r'^showall/$',views.showall_view),
# ]
from django.urls import path
from . import views
urlpatterns = [
path('upload/', views.upload_view),
path('showall/', views.showall_view),
]
创建视图
- stuapp/views.py
# -*- coding: utf-8 -*-
# from __future__ import unicode_literals
#
# from django.http import HttpResponse, HttpResponseRedirect
# from django.shortcuts import render
#
# Create your views here.
# from stu.models import Student
#
# 显示注册页面
# def index_view(request):
#
# return render(request,'index.html')
#
#
# django文件上传
# def upload1_view(request):
# #1.获取请求参数
# sname = request.POST.get('sname')
# photo = request.FILES.get('photo')
#
# #2.插入数据库
# stu = Student.objects.create(sname=sname,photo=photo)
#
# #3.判断是否注册成功
# if stu:
# return HttpResponse('注册成功!')
#
# return HttpResponseRedirect('/stu/')
#
# 显示所有学生信息
# def showall_view(request):
# #查询所有学生信息
# stus = Student.objects.all()
#
# return render(request,'show.html',{'stus':stus})
from django.http import HttpResponse, Http404
from django.shortcuts import render
# Create your views here.
from stuapp.models import Student
def upload_view(request):
# 判断当前请求方式
if request.method == "GET":
return render(request, "upload.html")
elif request.method == "POST":
# 获取请求对象
sname = request.POST.get("sname", "")
age = request.POST.get("age", "")
photo = request.FILES.get("photo", "")
# 校验上传图片的格式(png/jpg)
# 获取文件的扩展名
extendsname = photo.name[photo.name.rindex(".") + 1:] # rindex(".") 获取字符串最后一个 "." 的索引
# 判断上传文件是否符合格式要求
allowedes = ["png", "jpg"]
if extendsname not in allowedes:
raise Exception
# 将数据保存到数据库
stuObj = Student.objects.create(sname=sname, age=age, photo=photo)
# 判断是否注册成功
if stuObj:
return HttpResponse("注册成功!")
return HttpResponse("注册失败!")
def showall_view(request):
# 查询数据库中所有数据
stus = Student.objects.all()
return render(request, "show.html", {"stus": stus})
创建模板
- templates/upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/student/upload/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>姓名:<input type="text" name="sname"></p>
<p>年龄:<input type="text" name="age"></p>
<p>头像:<input type="file" name="photo"></p>
<p>   <input type="submit" value="注册"></p>
</form>
</body>
</html>
- templates/show.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1" cellspacing="0" width="500px">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>头像</th>
<th>操作</th>
</tr>
{% for stu in stus %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ stu.sname }}</td>
<td>{{ stu.age }}</td>
<td><img width="150px" src="/media/{{ stu.photo }}"></td>
<td>操作</td>
</tr>
{% endfor %}
</table>
</body>
</html>
头像读取相关settings.py文件中的设置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.media'#配置这句话
],
},
},
]
38_文件下载
文件下载
配置URL
#coding=utf-8
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'^download/(.*)$', views.download_view),
]
创建视图
def download_view(request, photoname):
# 接收请求参数
flag = request.GET.get("flag", "")
# 获取上传文件名
# imgs/1.jpg
# 获取文件名
filename = photoname[photoname.rindex("/") + 1:]
print(filename)
# 获取文件所在的存储位置
url = os.path.join(MEDIA_ROOT, photoname)
print(url)
# 预览模式
with open(url, "rb") as fr:
content = fr.read()
reaponse = HttpResponse(content, content_type="image/jpeg")
if flag == "2":
# 附件下载模式
reaponse["Content-Disposition"] = "attachment;filename=" + filename # 设置响应头
return reaponse
show.html
<td>
<a href="/student/download/{{ stu.photo }}?flag=1">预览查看</a>
<a href="/student/download/{{ stu.photo }}?flag=2">附件下载</a>
</td>
文件名中文情况
from django.utils.encoding import escape_uri_path
response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(file_name))
39_重定向_订制错误页面
HttpResponseRedirect('')
- 302重定向
redirect('')
- 301重定向
- 默认302请求可以改为301
- redirect('')
1.301:永久性重定向 2.302:临时性重定向
配置URL
from django.conf.urls import url
from django.contrib import admin
import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^r1/', views.r1_view),
url(r'^r2/', views.r2_view),
]
配置视图
#coding=utf-8
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import redirect
def r1_view(request):
#方式1:302
# return HttpResponseRedirect('/r2/')
#方式2:默认302可以转换成301
# return redirect('/r2/',permanent='True')
#方式3:
response = HttpResponse()
response.status_code=302
response.setdefault('Location','/r2/')
return response
def r2_view(request):
return HttpResponse('hello3')
案例:登录成功跳转成功页面,反之跳转到登录首页
订制错误页面
#1.在settings文件中修改
DEBUG = False
ALLOWED_HOSTS = ['*']
#2.在templates目录中创建404.html/500.html