1
MTV中的V表示View视图,视图接收web请求返回web响应,视图就是一个python函数被定义在view.py中,响应的结果可以是一个网页的html内容,一个重定向等等

配置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)    

视图函数

本质就是一个函数,视图的参数包含:

  1. 一个HttpRequest实例
  2. 通过正则表达式组获取的位置参数
  3. 通过正则表达式组获得的关键字参数

在应用目录下默认有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/')  

离岛
588 声望79 粉丝