【Django 010】Django2.2试图函数详解(二):通过HttpRequest对象获取GET和POST传递内容

上一小节我们成功从客户端访问的url中提取到了路径信息,但是路径里面包含的自定义信息毕竟少,更多的时候是通过查询参数和POST上去的内容。那么这一小节我们就来看看如何获取这些信息。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

操作环境

先总结下我的操作环境:

  • Centos 7
  • Python 3.7
  • Pycharm 2019.3
  • Django 2.2

因为Django长期支持版本2.2LTS和前一个长期支持版本1.11LTS有许多地方不一样,需要小心区分。

获取url的查询参数信息

实际场景的路径信息是不太频繁变换的,更多的请求信息都在查询参数当中,如果是POST场景下甚至都不在url里面。这些信息要怎么获取呢?需要借助于Django中的Request和Response对象了。这一节我们来认识一下这个Request对象,后面的小节我们再看Response。

Request和Response的详细说明可以参考官方文档

不管是GET或是POST方法,都会创建一个HttpRequest对象,Django会将这个对象传递给view函数的第一个参数request。同时每个view函数返回的一定是一个HttpResponse对象。

即使是render方法,返回的也是一个HttpResponse对象

通过这个HttpRequest对象的属性,不仅可以获得我们上面提到的信息,还有很多额外的东西可以提取出来。我们用实例来感受下。

创建路由以及view函数如下

path('sendrequest/',views.sendrequest),
def sendrequest(request):
    print(request.path)
    print(request.body)
    print(request.method)
    print(request.GET)
    print(request.POST)
    print(request.get_full_path())
    print(request.headers)
    return HttpResponse('Request Success.')

如果只是简单访问http://127.0.0.1:8000/two/sendrequest/,打印出来的内容如下

/two/sendrequest/
b''
GET
<QueryDict: {}>
<QueryDict: {}>
/two/sendrequest/
{'Content-Length': '', 'Content-Type': 'text/plain', 'Host': '127.0.0.1:8000', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36', 'Sec-Fetch-Dest': 'document', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Sec-Fetch-Site': 'none', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-User': '?1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Cookie': 'csrftoken=JsThoZrM2vXjwuRbpAiFPctv0wnVZdJrv6ACMojCttBADOYaQ21romkzRtd5gJ9T'}

可以看到,request.GETrequest.POST返回了一个QueryDict类型的数据,这是字典类型的一个子类,区别就在于key可以重复

QueryDict类型的官方文档

加一点查询参数进去试试,访问http://127.0.0.1:8000/two/sendrequest/?name=xiaofu&name=james&age=99&power=100,打印出来的内容如下

/two/sendrequest/
b''
GET
<QueryDict: {'name': ['xiaofu', 'james'], 'age': ['99'], 'power': ['100']}>
<QueryDict: {}>
/two/sendrequest/?name=xiaofu&name=james&age=99&power=100
{'Content-Length': '', 'Content-Type': 'text/plain', 'Host': '127.0.0.1:8000', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36', 'Sec-Fetch-Dest': 'document', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Sec-Fetch-Site': 'none', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-User': '?1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Cookie': 'csrftoken=JsThoZrM2vXjwuRbpAiFPctv0wnVZdJrv6ACMojCttBADOYaQ21romkzRtd5gJ9T'}

重点看一下request.GET返回的内容

<QueryDict: {'name': ['xiaofu', 'james'], 'age': ['99'], 'power': ['100']}>

这时候直接用key应该就能获取value了,我们来试试,修改view函数如下

def sendrequest(request):
    print(request.GET.get('name'))
    return HttpResponse('Request Success.')

但是却发现,如果value是一个list的话,通过key只能取出list的最后一个值

james

如果要取出整个list的话,需要用到另一个方法

def sendrequest(request):
    print(request.GET.getlist('name'))
    return HttpResponse('Request Success.')

打印出的结果如下

['xiaofu', 'james']

这里需要注意的是,即使查询参数只传递了一个值进来,也可以用getlist方法,此时获得的是一个单个元素的list,并不会报错

获取POST方法传递的内容

既然能获得GET方法传递的内容,当然获取POST方法也类似。同样用一个实例来验证一下。

首先创建路由和对应的view函数如下

path('submitinfo', views.submitinfo),
def submitinfo(request):
    return render(request,'submitinfo.html')

然后创建对应的h5页面submitinfo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sumbit Info</title>
</head>
<body>
<form action="{% url 'test_namespace:accept' %}" method="post">
    <label for="name">Name:</label><input type="text" name="name" id="name" placeholder="Please input your name">
    <br>
    <label for="age">Age:</label><input type="text" name="age" id="age" placeholder="Please input your age">
    <br>
    <input type="submit">
</form>
</body>
</html>

这里是采用反向解析的方式创建的action链接,对应的路由和view函数如下

path('acceptinfo', views.acceptinfo, name='accept'),
def acceptinfo(request):
    name = request.POST.get('name')
    age = request.POST.get('age')
    return HttpResponse('Name: {}, Age: {}'.format(name, age))

这时候如果在页面submitinfo.html中填好信息点击Submit的话,可能会在浏览器看到如下错误信息

Forbidden (403)
CSRF verification failed. Request aborted.

这里我们简便起见,直接先关闭Django中的CSRF中间件,在settings.py中注释掉下面这行

'django.middleware.csrf.CsrfViewMiddleware',

csrf技术我们后面还会再讲

再去尝试,像如下当时填写信息
1-form.png
点击Submit按钮后跳转到如下页面
2-post.png
说明提交上去的POST内容被成功捕获。

META信息

HttpRequest对象还有一个非常重要的属性叫做META,这里面包含了跟客户端有关的很多信息,甚至于包括用户名,home目录等等

view函数中request.META返回的是一个字典类型的数据,通过下面方法查看,具体结果因为涉及到太多个人机器信息我就不举例了,大家可以自己试试看。

for key in request.META:
        print(key, request.META.get(key))

自定义错误码页面

这里顺便补充一下错误码的页面重写。

如果想重写默认的错误页面,例如404页面,不需要任何路由或者view函数,直接在模板文件夹中加一个404.html即可。

因为没有修改到python代码,所以Django自带的测试服务器不会自动重启生效,必须手动重启。同时记得将settings.py中的DEBUG开关调整为False。

因为就近原则,我们重写的404页面会覆盖系统自带的404页面。如果想查看系统自带的404页面,可以点击右侧的放大镜进行全局搜索,或者是点击两下Shift调出全局搜索框。勾选Include Non-project items,然后搜索404。就会找到Admin/404.html页面了。

总结

这一小节我们通过HttpRequest对象获取到了我们想要的信息,下一小节我们来看看另一个更为强大的HttpResponse对象。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值