Django视图
配置URLconf
在settings.py文件中通过ROOT_URLCONF指定根级url的配置
urlpatterns是一个url()实例的列表
一个url()对象包括:
正则表达式
视图函数
名称name
编写URLconf的注意:
若要从url中捕获一个值,需要在它周围设置一对圆括号
不需要添加一个前导的反斜杠,如应该写作'test/',而不应该写作'/test/'
每个正则表达式前面的r表示字符串不转义
需要注意url匹配规则写在每个应用自己的urls.py文件内(文件自己创建,文字可以修改,一般不建议修改),不要写在根目录,不然很多个应用上面url会出现问题
在根目录的urls.py文件中添加自己指定的应用,也就是当用户访问只要url包含test1app的都会进入到这个应用自己的urls.py中,再次进行匹配
urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^test1app/'include('test1app.urls')) ]
在test1app新创建的urls.py中,配置代码如下:
from django.conf.urls import url from .views import * urlpatterns=[ url(r'^$',index) ]
并且在views.py中配置index对应的方法:
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def index(request): return HttpResponse('hello world')
这个时候我们通过python manage.py runserver 进行运行访问 http://127.0.0.1:8000/test1app时就会输出hello world在页面上。
如何传递参数呢?
在urls.py中添加一条规则,在正则中小括号表示获取(返回)
from django.conf.urls import url from .views import * urlpatterns=[ url(r'^$',index), url(r'^(\d+)$',detail) ]
在对应detail视图函数中,应该接收一个参数
from django.shortcuts import render from django.http import HttpResponse # Create your views here. #定义了一个index()函数,第一个参数必须是 request,与网页发来的请求有关,request 变量里面包含get或post的内容,用户浏览器,系统等信息在里面 def index(request): return HttpResponse('hello world') def detail(request,arg): return HttpResponse(arg)
运行访问地址 http://127.0.0.1:8000/test1app/123 会在页面上输出 123,当然你也可以对参数的名字进行指定,但是正则规则需要修改
from django.conf.urls import url from .views import * urlpatterns=[ url(r'^$',index), url(r'^(?P<id>\d+)$',detail) ]
在视图函数中参数名称就必须为id才可以
def detail(request,id): return HttpResponse(id)
视图函数
本质就是一个函数,视图的参数包含:
- 一个HttpRequest实例
- 通过正则表达式组获取的位置参数
- 通过正则表达式组获得的关键字参数
在应用目录下默认有views.py文件,一般视图都定义在这个文件中,如果处理功能过多,可以将函数定义到不同的py文件中
在应用中定义一个views1.py文件,定义视图函数
from django.http import HttpResponse def index(request): return HttpResponse("hello 123")
在urls.py中,引入views1.py,在匹配规则时,使用views1.py中的视图函数即可
from django.conf.urls import url from .views import * from .views1 import * #自己新定义的视图 urlpatterns=[ url(r'^$',index,name='index'), # url(r'^$',index,name='index'), url(r'^(?P<id>\d+)$',detail,'detail') ]
Django自带默认视图
Django原生自带几个默认视图用于处理HTTP错误:
404 (page not found) 视图
在urls.py中去检测正则表达式匹配,如果没有匹配的内容会调用404视图,使用自带的404视图,需要注意首先需要将setting.py中的DEBUG设置为False,否则不会调用404.
DEBUG = False ALLOWED_HOSTS = ['*']
前期准备好了以后需要创建404错误模板,在项目根目录创建templates文件夹,创建404.html页面,里面编写内容({{request_path}}),在setting中配置视图模板的地址
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR,'templates')], ... }
准备就绪,访问一个错误的地址 http://127.0.0.1:8000/test1app/aa 就会出现404.html
500 (server error) 视图
创建505.html,在里面编写内容,步骤同404.html
400 (bad request) 视图
创建400.html,在里面编写内容,步骤同404.html
HttpRequest对象
服务器接收到http协议的请求后,会根据报文创建HttpRequest对象,视图函数的第一个参数是HttpRequest对象,在django.http模块中定义了HttpRequest对象的API。
属性
下面除非特别说明,属性都是只读的
path:一个字符串,表示请求的页面的完整路径,不包含域名
method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'
encoding:一个字符串,表示提交的数据的编码方式
如果为None则表示使用浏览器的默认设置,一般为utf-8
这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值
GET:一个类似于字典的对象,包含get请求方式的所有参数
POST:一个类似于字典的对象,包含post请求方式的所有参数
FILES:一个类似于字典的对象,包含所有的上传文件
COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串
session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见“状态保持”
方法
is_ajax():如果请求是通过XMLHttpRequest发起的,则返回True
取GET方式的参数:
request对象的属性GET、POST都是QueryDict类型的对象,与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
方法get():根据键获取值(只能获取键的一个值,如果一个键同时拥有多个值,获取最后一个值)
取一个值:
模板中地址: <a href="/test1app/getTest2/?a=1&b=2&c=3">test2</a> 视图函数: def getTest2(request): #根据键接收值 a1=request.GET['a'] b1=request.GET['b'] c1=request.GET['c'] #构造上下文 context1={'a':a1,'b':b1,'c':c1} #向模板中传递上下文,并进行渲染 return render(request,'test1app/getTest2.html',context=context1)
取多个值:
模板中地址: <a href="/test1app/getTest3/?a=1&a=2&c=3">test3</a> 视图函数: def getTest3(request): a1=request.GET.getlist('a') context={'a':a1} return render(request,'test1app/getTest3.html',context)
取POST请求传参的参数:
<body> <form method="POST" action="/test1app/postTest2"> 用户名:<input type="text" name="uname" /><br/> 密码:<input type="password" name="upwd" /><br/> 性别:<input type="radio" value="女" checked="checked" name="ugender" />女 <input type="radio" name="ugender" value="男" />男 爱好:<input type="checkbox" name="uhobby" value="吃饭" />吃饭<input type="checkbox" name="uhobby" value="睡觉" />睡觉<input type="checkbox" name="uhobby" value="打豆豆" />打豆豆 <input type="submit" value="提交"/> </form> </body>
def postTest2(request): name=request.POST.get("uname") pwd=request.POST.get("upwd") gender=request.POST.get("ugender") hobby=request.POST.getlist("uhobby") context={"name":name,"pwd":pwd,"gender":gender,"hobby":hobby} return render(request,'test1app/postTest2.html',context)
HttpResponse
HttpRequest对象由Django自动创建,HttpResponse对象由程序员创建,用于做出响应
不调用模板,直接返回数据
def index(request): return HttpResponse('你好')
调用模板
def index(request): return render(request, 'booktest/index.html', {'h1': 'hello'})
重定向
from django.shortcuts import render from django.http import HttpResponse,HttpResponseRedirect def redTest1(request): return HttpResponseRedirect('/test1app/redTest2/') def redTest2(request): return HttpResponse('结果页面') #简写版的重定向 from django.shortcuts import render,redirect from django.http import HttpResponse,HttpResponseRedirect def redTest1(request): return redirect('/test1app/redTest2/') def redTest2(request): return HttpResponse('结果页面')
session
状态保持:http协议是无状态的,每次请求都是一次新的请求,不会记得之前通信的状态,客户端与服务器端的一次通信,就是一次会话.
想要达到状态保持可以在客户端(cookie)或者服务器端(session)存储和会话有关的数据,但是需要注意一般我们并不建议在cookie中存储敏感数据,因为不太安全。推荐的方式是使用session存储在服务器端,在客户端cookie中存储session_id
使用session
启用会话后,每个HttpRequest对象将具有一个session属性,它是一个类字典对象
get(key, default=None):根据键获取会话的值
clear():清除所有会话
flush():删除当前的会话数据并删除会话的Cookie
del request.session['member_id']:删除会话
#通过用户登录练习session def session1(request): uname=request.session['myname'] context={"name":uname} return render(request,'test1app/session1.html',context) def session2(request): #表单页面 return render(request,'test1app/session2.html') def session2_handle(request): #表单提交到页面 #获取提交的值 uname=request.POST["uname"] #保存到session中 request.session['myname']=uname return redirect('/test1app/session1/') def session3(request): #删除session del request.session["myname"] return redirect('/test1app/session1/')