五、视图层(一)
一、URLconf配置(正向传参)
#### Django如何处理一个请求
当一个用户通过网页发送一个请求给Django网站,Django执行过程如下:
1. 首先访问项目下的settings.py文件中 ROOT_URLCONF = 'test1.urls'
2. 执行项目包下的urls.py文件中的urlpatterns列表
3. 执行应用包下的urls.py文件中的urlpatterns列表
4. 根据匹配的url正则调用相应的视图函数/通用视图
5. 如果没有匹配的正则,将会自动调用Django错误处理页面
1. 首先访问项目下的settings.py文件中 ROOT_URLCONF = 'test1.urls'
2. 执行项目包下的urls.py文件中的urlpatterns列表
3. 执行应用包下的urls.py文件中的urlpatterns列表
4. 根据匹配的url正则调用相应的视图函数/通用视图
5. 如果没有匹配的正则,将会自动调用Django错误处理页面
#### url函数配置方式
- 方式1
```
#student/urls.py
- 方式1
```
#student/urls.py
#coding=utf-8
from django.conf.urls import url
from . import views
from . import views
urlpatterns=[
url(r'^query$',views.queryAll)
url(r'^query$',views.queryAll)
]
#student/views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render
from django.shortcuts import render
# Create your views here.
def queryAll(request):
return HttpResponse('hello world')
#访问地址
http://127.0.0.1:8000/student/query
http://127.0.0.1:8000/student/query
```
- 方式2:位置传参
```
#student/urls.py
#coding=utf-8
from django.conf.urls import url
from . import views
from . import views
urlpatterns=[
url(r'^query$',views.queryAll),
url(r'^query/(\d{2})$',views.queryAll),
url(r'^query$',views.queryAll),
url(r'^query/(\d{2})$',views.queryAll),
]
#student/views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render
from django.shortcuts import render
# Create your views here.
def queryAll(request,sno):
print sno
return HttpResponse('hello world')
print sno
return HttpResponse('hello world')
#访问地址
http://127.0.0.1:8000/student/query/12
```
- 方式3:关键字传参
```
urlpatterns=[
url(r'^query$',views.queryAll),
url(r'^query/(\d{2})$',views.queryAll),
url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
```
urlpatterns=[
url(r'^query$',views.queryAll),
url(r'^query/(\d{2})$',views.queryAll),
url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
]
def queryAll(request,year,day,month):
print year,month,day
return HttpResponse('hello world')
#访问地址
http://127.0.0.1:8000/student/query/2008/10/12/
```
- 方式4:加载其他映射文件
```
from django.conf.urls import include, url
```
from django.conf.urls import include, url
urlpatterns = [
url(r'^community/', include('aggregator.urls')),
url(r'^community/', include('aggregator.urls')),
]
```
- 方式5:传参(参数名必须保持一致)
```
urlpatterns=[
url(r'^query$',views.queryAll),
url(r'^query/(\d{2})$',views.queryAll),
url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
url(r'^query/(?P<num1>\d{3})/$',views.queryAll,{'hello':'123'}),
]
```
urlpatterns=[
url(r'^query$',views.queryAll),
url(r'^query/(\d{2})$',views.queryAll),
url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
url(r'^query/(?P<num1>\d{3})/$',views.queryAll,{'hello':'123'}),
]
def queryAll(request,num1,hello):
print num1,hello
return HttpResponse('hello world')
#访问地址
http://127.0.0.1:8000/student/query/888/
```
print num1,hello
return HttpResponse('hello world')
#访问地址
http://127.0.0.1:8000/student/query/888/
```
二、URLConf配置 (反向传参)
#应用包/views.py
from django.views import View
class Index(View):
def get(self,request):
return render(request,'index.html')
class Login(View):
def get(self,request):
return HttpResponse('hello')
#templates/index.html
```
```
```
#### 配置URL
```
- stu/urls.py
```
#coding=utf-8
```
{% endfor %}
</table>
</body>
</html>
#### 创建视图
```
#### 逆向解析(防止硬编码)
```
```
方式一
‘’‘’‘
#student/urls.py
#student/urls.py
from django.conf.urls import url
from . import views
from . import views
urlpatterns=[
url(r'^query$',views.queryAll),
url(r'^query/(\d{2})$',views.queryAll),
url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
url(r'^query/(?P<num1>\d{3})/$',views.queryAll,{'hello':'123'}),
url(r'^query1/([0-9]{4})/$', views.queryAll, name='hello'),
url(r'^$', views.index_view),
]
url(r'^query$',views.queryAll),
url(r'^query/(\d{2})$',views.queryAll),
url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
url(r'^query/(?P<num1>\d{3})/$',views.queryAll,{'hello':'123'}),
url(r'^query1/([0-9]{4})/$', views.queryAll, name='hello'),
url(r'^$', views.index_view),
]
#student/views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render
from django.shortcuts import render
# Create your views here.
def queryAll(request,num1):
print num1
return HttpResponse('hello world')
print num1
return HttpResponse('hello world')
#通过模板页面逆向访问
def index_view(request):
return render(request,'index.html')
def index_view(request):
return render(request,'index.html')
#通过Python代码逆向访问
def index_view(request):
# return render(request,'index.html')
return HttpResponseRedirect(reverse('hello',args=(2018,)))
def index_view(request):
# return render(request,'index.html')
return HttpResponseRedirect(reverse('hello',args=(2018,)))
#templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="{% url 'hello' 2008 %}">访问</a>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="{% url 'hello' 2008 %}">访问</a>
</body>
</html>
</html>
```
方式2
```
方式2
```
#项目包/urls.py
from django.conf.urls import url, include
from django.contrib import admin
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^student/', include('student.urls',namespace='stu',app_name='student')),
]
url(r'^admin/', admin.site.urls),
url(r'^student/', include('student.urls',namespace='stu',app_name='student')),
]
#应用包/urls.py
#coding=utf-8
from django.conf.urls import url
from . import views
from . import views
urlpatterns=[
url(r'^$', views.Index.as_view()),
url(r'^query2/',views.Login.as_view(),name='login')
]
url(r'^query2/',views.Login.as_view(),name='login')
]
#应用包/views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import unicode_literals
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.shortcuts import render
from django.urls import reverse
from django.views import View
class Index(View):
def get(self,request):
return render(request,'index.html')
class Login(View):
def get(self,request):
return HttpResponse('hello')
#templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="{% url 'stu:login' %}">访问</a>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="{% url 'stu:login' %}">访问</a>
</body>
</html>
</html>
```
三、文件上传
#### Django文件上传
#### 需求
1. 完成学生信息注册操作
2. 将学生信息入库
3. 将上传文件存放至项目下media文件夹下
4. 显示所有学生信息
1. 完成学生信息注册操作
2. 将学生信息入库
3. 将上传文件存放至项目下media文件夹下
4. 显示所有学生信息
#### 创建模型类
```
class Student(models.Model):
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30)
photo = models.ImageField(upload_to='imgs')
```
class Student(models.Model):
sno = models.AutoField(primary_key=True)
sname = models.CharField(max_length=30)
photo = models.ImageField(upload_to='imgs')
class Meta:
db_table = 't_stu'
db_table = 't_stu'
def __unicode__(self):
return u'Student:%s'%self.sname
return u'Student:%s'%self.sname
```
#### settings.py文件中文件上传相关设置
```
INSTALLED_APPS = [
...
'stu'
]
```
INSTALLED_APPS = [
...
'stu'
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
```
#### 映射数据库表
```
#在终端中敲命令
python manage.py makemigrations stu
python manage.py migrate
#在终端中敲命令
python manage.py makemigrations stu
python manage.py migrate
```
#### 配置URL
- test13/urls.py
```
#coding=utf-8
from django.conf.urls import url, include
from django.contrib import admin
```
#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')),
]
url(r'^admin/', admin.site.urls),
url(r'^stu/', include('stu.urls')),
]
#配置路由读取后台上传文件
from django.views.static import serve
from django.views.static import serve
if DEBUG:
urlpatterns+=url(r'^media/(?P<path>.*)/$', serve, {"document_root": MEDIA_ROOT}),
urlpatterns+=url(r'^media/(?P<path>.*)/$', serve, {"document_root": MEDIA_ROOT}),
```
- stu/urls.py
```
#coding=utf-8
from django.conf.urls import url
import views
import views
urlpatterns=[
url(r'^$',views.index_view),
url(r'^upload1/$',views.upload1_view),
url(r'^showall/$',views.showall_view),
]
url(r'^$',views.index_view),
url(r'^upload1/$',views.upload1_view),
url(r'^showall/$',views.showall_view),
]
```
#### 创建视图
- stu/views.py
```
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
```
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from django.shortcuts import render
# Create your views here.
from stu.models import Student
from stu.models import Student
#显示注册页面
def index_view(request):
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')
#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)
stu = Student.objects.create(sname=sname,photo=photo)
#3.判断是否注册成功
if stu:
return HttpResponse('注册成功!')
if stu:
return HttpResponse('注册成功!')
return HttpResponseRedirect('/stu/')
#显示所有学生信息
def showall_view(request):
#查询所有学生信息
stus = Student.objects.all()
def showall_view(request):
#查询所有学生信息
stus = Student.objects.all()
return render(request,'show.html',{'stus':stus})
```
#### 创建模板
- templates/index.html
```
<form action="/stu/upload1/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>
<label for="sname">姓名:</label><input type="text" name="sname" id="sname"/>
</p>
<p>
<label for="photo">头像:</label><input type="file" name="photo" id="photo"/>
</p>
<p>
  <input type="submit" value="注册" />
</p>
```
<form action="/stu/upload1/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>
<label for="sname">姓名:</label><input type="text" name="sname" id="sname"/>
</p>
<p>
<label for="photo">头像:</label><input type="file" name="photo" id="photo"/>
</p>
<p>
  <input type="submit" value="注册" />
</p>
</form>
```
- templates/show.html
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
img{
width: 200px;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
img{
width: 200px;
}
</style>
</head>
<body>
<table border="1" width="500px" cellspacing="0">
<tr>
<th>编号</th>
<th>姓名</th>
<th>头像</th>
<th>操作</th>
</tr>
{% for stu in stus %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ stu.sname }}</td>
<td><img src="{{ MEDIA_URL }}{{ stu.photo }}"/></td>
<td>操作</td>
</tr>
</style>
</head>
<body>
<table border="1" width="500px" cellspacing="0">
<tr>
<th>编号</th>
<th>姓名</th>
<th>头像</th>
<th>操作</th>
</tr>
{% for stu in stus %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ stu.sname }}</td>
<td><img src="{{ MEDIA_URL }}{{ 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'#配置这句话
],
},
},
]
{
'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'#配置这句话
],
},
},
]
```
四、文件下载
#### 配置URL
```
#coding=utf-8
#coding=utf-8
from django.conf.urls import url
from . import views
from . import views
urlpatterns=[
url(r'^$', views.Index.as_view()),
url(r'^stulist/$', views.StuList.as_view()),
url(r'^download/$', views.Download.as_view()),
url(r'^$', views.Index.as_view()),
url(r'^stulist/$', views.StuList.as_view()),
url(r'^download/$', views.Download.as_view()),
]
```
#### 创建视图
```
class Download(View):
def get(self,request):
#获取文件存放位置
filepath = request.GET.get('photo','')
#获取文件名
filename = filepath[filepath.rindex('/')+1:]
class Download(View):
def get(self,request):
#获取文件存放位置
filepath = request.GET.get('photo','')
#获取文件名
filename = filepath[filepath.rindex('/')+1:]
#获取文件绝对路径
path = os.path.join(os.getcwd(),'media',filepath.replace('/','\\'))
path = os.path.join(os.getcwd(),'media',filepath.replace('/','\\'))
with open(path,'rb') as fr:
response = HttpResponse(fr.read())
response['Content-Type']='image/png'
#预览模式
response['Content-Disposition']='inline;filename='+filename
#附件模式
# response['Content-Disposition']='attachment;filename='+filename
response = HttpResponse(fr.read())
response['Content-Type']='image/png'
#预览模式
response['Content-Disposition']='inline;filename='+filename
#附件模式
# response['Content-Disposition']='attachment;filename='+filename
return response
```
#### 文件名中文情况
```
from django.utils.encoding import escape_uri_path
response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(file_name))
```