Django入门(十二) 视图views

1. 视图层views介绍

视图层是一个视图函数,简称视图,是一个简单的 Python 函数,它接受 Web 请求并且返回 Web 响应。

视图层中有两个重要的对象:请求对象(HttpRequest)与响应对象(HttpResponse)。

每个视图函数都负责返回也就是return 一个 HttpResponse 响应对象,HttpResponse 响应对象包括HttpResponse()、render()、redirect()三种形式。

响应可以是一个 HTML 页面、一个 404 错误页面、重定向页面、XML 文档、或者一张图片...

无论视图本身包含什么逻辑,都要返回响应。代码写在哪里都可以,只要在 Python 目录下面,一般放在项目的 views.py 文件中。

2. 请求对象:  又叫HttpRequest 对象,简称request对象

每个视图函数的第一个参数是一个 HttpRequest 对象

1. 属性

HttpRequest对象(request对象)包含如下属性:

属性

描述

path

请求页面的全路径,不包括域名—例如, "/hello/"。

method

请求中使用的HTTP方法的字符串表示。全大写表示。例如:

if request.method == 'GET':
    do_something()
elif request.method == 'POST':
    do_something_else()

GET

包含所有HTTP GET参数的类字典对象。参见QueryDict 文档。

POST

包含所有HTTP POST参数的类字典对象。参见QueryDict 文档。

服务器收到空的POST请求的情况也是有可能发生的。也就是说,表单form通过HTTP POST方法提交请求,但是表单中可以没有数据。因此,不能使用语句if request.POST来判断是否使用HTTP POST方法;应该使用if request.method == "POST" (参见本表的method属性)。

注意: POST不包括file-upload信息。参见FILES属性。

REQUEST

为了方便,该属性是POST和GET属性的集合体,但是有特殊性,先查找POST属性,然后再查找GET属性。借鉴PHP's $_REQUEST。

例如,如果GET = {"name": "john"} 和POST = {"age": '34'},则 REQUEST["name"] 的值是"john", REQUEST["age"]的值是"34".

强烈建议使用GET and POST,因为这两个属性更加显式化,写出的代码也更易理解。

COOKIES

包含所有cookies的标准Python字典对象。Keys和values都是字符串。

FILES

包含所有上传文件的类字典对象。FILES中的每个Key都是<input type="file" name="" />标签中name属性的值. FILES中的每个value 同时也是一个标准Python字典对象,包含下面三个Keys:

  • filename: 上传文件名,用Python字符串表示
  • content-type: 上传文件的Content type
  • content: 上传文件的原始内容

注意:只有在请求方法是POST,并且请求页面中<form>有enctype="multipart/form-data"属性时FILES才拥有数据。否则,FILES 是一个空字典。

META

包含所有可用HTTP头部信息的字典。 例如:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • QUERY_STRING: 未解析的原始查询字符串
  • REMOTE_ADDR: 客户端IP地址
  • REMOTE_HOST: 客户端主机名
  • SERVER_NAME: 服务器主机名
  • SERVER_PORT: 服务器端口

META 中这些头加上前缀 HTTP_ 为 Key, 冒号(:)后面的为 Value, 例如:

  • HTTP_ACCEPT_ENCODING
  • HTTP_ACCEPT_LANGUAGE
  • HTTP_HOST: 客户发送的HTTP主机头信息
  • HTTP_REFERER: referring页
  • HTTP_USER_AGENT: 客户端的user-agent字符串
  • HTTP_X_BENDER: X-Bender头信息

user

是一个django.contrib.auth.models.User 对象,代表当前登录的用户。

如果访问用户当前没有登录,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。

你可以通过user的is_authenticated()方法来辨别用户是否登录:

if request.user.is_authenticated():
    # Do something for logged-in users.
else:
    # Do something for anonymous users.

只有激活Django中的AuthenticationMiddleware时该属性才可用

session

唯一可读写的属性,代表当前会话的字典对象。只有激活Django中的session支持时该属性才可用。

raw_post_data

原始HTTP POST数据,未解析过。 高级处理时会有用处。

2. 方法

Request对象也有一些有用的方法:

方法描述
__getitem__(key)返回GET/POST的键值,先取POST,后取GET。如果键不存在抛出 KeyError。
这是我们可以使用字典语法访问HttpRequest对象。
例如,request["foo"]等同于先request.POST["foo"] 然后 request.GET["foo"]的操作。
has_key()检查request.GET or request.POST中是否包含参数指定的Key。
get_full_path()返回包含查询字符串的请求路径。例如, "/music/bands/the_beatles/?print=true"
is_secure()如果请求是安全的,返回True,就是说,发出的是HTTPS请求。

3. QueryDict对象(GET,POST)的方法

在HttpRequest对象中, GET和POST属性是django.http.QueryDict类的实例。

QueryDict类似字典的自定义类,用来处理单键对应多值的情况。

QueryDict实现所有python中已有的字典方法比如get(),items()等以及一些特有的方法,如下表:

方法描述

__getitem__

和标准字典的处理有一点不同,就是,如果Key对应多个Value,__getitem__()返回最后一个value。

__setitem__

设置参数指定key的value列表(一个Python list)。注意:它只能在一个mutable QueryDict 对象上被调用(就是通过copy()产生的一个QueryDict对象的拷贝).

get()

如果key对应多个value,get()返回最后一个value。

update()

参数可以是QueryDict,也可以是标准字典。和标准字典的update方法不同,该方法添加字典 items,而不是替换它们:

>>> q = QueryDict('a=1')

>>> q = q.copy() # to make it mutable

>>> q.update({'a': '2'})

>>> q.getlist('a')

 ['1', '2']

>>> q['a'] # returns the last

['2']

items()

和标准字典的items()方法有一点不同,该方法使用单值逻辑的__getitem__():

>>> q = QueryDict('a=1&a=2&a=3')

>>> q.items()

[('a', '3')]

values()

和标准字典的values()方法有一点不同,该方法使用单值逻辑的__getitem__():

还有一些独有的方法:

方法描述

copy()

返回对象的拷贝,内部实现是用Python标准库的copy.deepcopy()。该拷贝是mutable(可更改的) — 就是说,可以更改该拷贝的值。

getlist(key)

返回和参数key对应的所有值,作为一个Python list返回。如果key不存在,则返回空list。 It's guaranteed to return a list of some sort..

setlist(key,list_)

设置key的值为list_ (unlike __setitem__()).

appendlist(key,item)

添加item到和key关联的内部list.

setlistdefault(key,list)

和setdefault有一点不同,它接受list而不是单个value作为参数。

lists()

和items()有一点不同, 它会返回key的所有值,作为一个list, 例如:

>>> q = QueryDict('a=1&a=2&a=3')

>>> q.lists()

[('a', ['1', '2', '3'])]

urlencode()

返回一个以查询字符串格式进行格式化后的字符串(例如:"a=2&b=3&b=5")。

4. 常用属性

 以下详细介绍几个常用的 request 属性。

1、GET

数据类型是 QueryDict,一个类似于字典的对象,包含 HTTP GET 的所有参数。

有相同的键,就把所有的值放到对应的列表里。

取值格式:对象.方法。

get():返回字符串,如果该键对应有多个值,取出该键的最后一个值。

代码举例:

新建一个newa.html

在urls.py中输入如下代码:

from django.urls import path
from . import views

urlpatterns = [

    path('newa/', views.mydefC)
]

 在views.py中

from django.http import HttpResponse


def mydefC(request):
    name=request.GET.get("name")
    return HttpResponse("姓名:{}".format(name))

在浏览器中输入如下:

?的意思是后面是参数,

浏览器反馈如下图,证明get对象ok

 

2、POST

数据类型是 QueryDict,一个类似于字典的对象,包含 HTTP POST 的所有参数。

常用于 form 表单,form 表单里的标签 name 属性对应参数的键,value 属性对应参数的值。

取值格式: 对象.方法。

get():返回字符串,如果该键对应有多个值,取出该键的最后一个值。

代码演示之前需要下载安装postman这个软件:

1. postman下载地址;Download Postman | Get Started for Free

点击下载安装 

2. 下载安装后,注册,免费登录,new collection----->点击加号

3.  在urls.py中输入如下代码:

from django.urls import path
from . import views

urlpatterns = [

    path('newa/', views.mydefC)
]

4. 在views.py中 ,使用POST方法,代码如下:

from django.http import HttpResponse

def mydefC(request):
    name=request.POST.get("name")
    return HttpResponse("姓名:{}".format(name))

5. 然后在POSTMAN中,选色POST,URL输入地址,选择body,forms-data, key下面输入name,Value下面输入张三, 然后send

可见下面出现:姓名:张三   

而真正的网页显示如下: 

6. 其间出现如下 CSRF verification failed. Request aborted. 报错,

解决办法:

.在setting.py 里注释掉 # ‘django.middleware.csrf.CsrfViewMiddleware’ 

3、body 

数据类型是二进制字节流,是原生请求体里的参数内容,在 HTTP 中用于 POST,因为 GET 没有请求体。

在 HTTP 中不常用,而在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML、Json 等。

1. 在views.py中 ,使用body方法,代码如下:

from django.http import HttpResponse

def mydefC(request):
    name=request.body
    print(name)
    return HttpResponse("姓名")

2. 然后在postman里面重复步骤和POST 方法内的步骤,其实也不需要重新输入,直接点击send,

反馈的只是httpresponse里面的内容“姓名”, 因为reques.body无法显示,所以只能用print函数,

 在cmd窗口中可以看到print函数打印出来的结果,是一串二进制字节流。

4、path

获取 URL 中的路径部分,数据类型是字符串。

 1. 在views.py中 ,使用body方法,代码如下:

改成name= request.path

from django.http import HttpResponse

def mydefC(request):
    name=request.path
    print(name)
    return HttpResponse("姓名")

2. 然后在postman里面重复步骤和POST 方法内的步骤,其实也不需要重新输入,直接点击send,内容和上面的body方法完全一样

3.  但是在cmd中可以看到打印的name,就是path

5、method

获取当前请求的方式,数据类型是字符串,且结果为大写。

 1. 在views.py中 ,使用body方法,代码如下:

改成name= request.method ,其他不变

from django.http import HttpResponse

def mydefC(request):
    name=request.method
    print(name)
    return HttpResponse("姓名")

2. 然后在postman里面重复步骤和POST 方法内的步骤,其实也不需要重新输入,直接点击send,内容和上面的body方法完全一样 

 3.  但是在cmd中可以看到打印的我们用的请求的方法POST,如果我们用get方法,就会显示get方法

3. 响应对象:HttpResponse 对象 

响应对象主要有三种形式:HttpResponse()、render()、redirect()。

HttpResponse(): 返回文本,参数为字符串,字符串中写文本内容。如果参数为字符串里含有 html 标签,也可以渲染。

 render(): 返回文本,第一个参数为 request,第二个参数为字符串(页面名称),第三个参数为字典(可选参数,向页面传递的参数:键为页面参数名,值为views参数名)。

redirect():重定向,跳转新页面。参数为字符串,字符串中填写页面路径。一般用于 form 表单提交后,跳转到新页面。

1. HttpResponse()

 1. 在views.py中 ,使用HttpResponse(), 代码如下:

from django.http import HttpResponse

def mydefC(request):
    
    return HttpResponse("我爱中国")

2. 在路由newa中映射到views.mydefC,就能显示如下:

3. 如果将 HttpResponse()里面的内容改成一串代码,也可以执行:

from django.http import HttpResponse

def mydefC(request):
    
    return HttpResponse("<a href='https://blog.csdn.net/weixin_42888180?spm=1000.2115.3001.5343'>我的主页</a>")

4. 网页显示:超链接

 2. render() 

 1. 在views.py中 ,使用render(), 代码如下:

注意:此时import 的是render

from django.shortcuts import render  #注意这行代码有变化

def mydefC(request):

     name="张三"
    return render(request,"newa.html",{"abc":name})

2.  在newa.html 中输入: <ul>{{abc}}</ul>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<ul>{{abc}}</ul>
</body>
</html>

2. 网页显示 ,成功!render中响应了一个网页,因此会打开这个网页,并且该网页里面有一个参数叫abc,并传入了一个这个参数的值name

 2. redirect()

 1. 在views.py中 ,使用redirect(), 代码如下:

注意:此时import 的是redirect

from django.shortcuts import  redirect

    def mydefC(request):

           return redirect("/base/")

2. 在地址栏输入: http://127.0.0.1:8002/newa/     结果显示:报错了 !没有redirect成功?

3. 此时,需要在 urls.py中输入2个路由

urlpatterns = [

    path('newa/', views.mydefC),
    path('base/', views.mydefB),
]

同时, 在views.py中定义mydefB,

def mydefC(request):

    return redirect("/base/")

def mydefB(request):

    return render(request,"base.html")

之前定义的base.html代码如下:不用改变

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DOTmanager教程</title>
</head>
<body>
  <h1>hello world!</h1>
  <p>Django 测试</p>
  {%block body%}
  <p>original</p>
  {%endblock%}
</body>
</html>

4.最终在地址栏输入newa.html的地址会自动跳转到base.html 

实际上: render 和 redirect 是在 HttpResponse 的基础上进行了封装:

    • render:底层返回的也是 HttpResponse 对象
    • redirect:底层继承的是 HttpResponse 对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DOT Manager

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值