一 视图函数

视图函数,简称视图,属于Django的视图层,默认定义在views.py文件中,是用来处理web请求信息以及返回响应信息的函数,所以研究视图函数只需熟练掌握两个对象即可:请求对象(HttpRequest)和响应对象(HttpResponse)

二 请求对象(HttpRequest)

django将http协议请求报文中的请求行、首部信息、内容主体封装到了HttpRequest对象中(类似于我们自定义框架的environ参数)。 django会将HttpRequest对象当做参数传给视图函数的第一个参数request,在视图函数中,通过访问该对象的属性便可以提取http协议的请求数据

2.1、HttpRequest对象常用属性part1

  1. 一.HttpRequest.method
  2. 获取请求使用的方法(值为纯大写的字符串格式)。例如:"GET""POST"
  3. 应该通过该属性的值来判断请求方法
  4. 二.HttpRequest.GET
  5. 值为一个类似于字典的QueryDict对象,封装了GET请求的所有参数,可通过HttpRequest.GET.get('键')获取相对应的值
  6. 三.HttpRequest.POST
  7. 值为一个类似于字典的QueryDict对象,封装了POST请求所包含的表单数据,可通过HttpRequest.POST.get('键')获取相对应的值
  8. 针对表单中checkbox类型的input标签、select标签提交的数据,键对应的值为多个,需要用: HttpRequest.POST.getlist("hobbies")获取存有多个值的列表,同理也有HttpRequest.GET.getlist("键")

案例:

urls.py

  1. from django.urls import re_path
  2. from app01 import views
  3. urlpatterns = [
  4. re_path(r'^login/$',views.login),
  5. ]

Views.py

  1. from django.shortcuts import render,HttpResponse
  2. def login(request):
  3. if request.method == 'GET':
  4. # 当请求url为:http://127.0.0.1:8001/login/?a=1&b=2&c=3&c=4&c=5
  5. # 请求方法是GET,?后的请求参数都存放于request.GET中
  6. print(request.GET)
  7. # 输出<QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['3', '4', '5']}>
  8. # 获取?后参数的方式为
  9. a=request.GET.get('a') # 1
  10. b=request.GET.get('b') # 2
  11. c=request.GET.getlist('c') # ['3', '4', '5']
  12. return render(request,'login.html')
  13. elif request.method == 'POST':
  14. # 在输入框内输入用户名egon、年龄18,选择爱好,点击提交
  15. # 请求方法为POST,表单内的数据都会存放于request.POST中
  16. print(request.POST)
  17. # 输出<QueryDict: {..., 'name': ['egon'], 'age': ['18'], 'hobbies': ['music', 'read']}>
  18. # 获取表单中数据的方式为
  19. name=request.POST.get('name') # egon
  20. age=request.POST.get('age') # 18
  21. hobbies=request.POST.getlist('hobbies') # ['music', 'read']
  22. return HttpResponse('提交成功')

在templates目录下新建login.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>登录页面</title>
  6. </head>
  7. <body>
  8. <!--
  9. method="post"代表在提交表单时会以POST方法提交表单数据
  10. action="/login/" 代表表单数据的提交地址为http://127.0.0.1:8001/login/,可以简写为action="/login/",或者action=""
  11. -->
  12. <form action="http://127.0.0.1:8001/login/" method="post">
  13. {% csrf_token %} <!--强调:必须加上这一行,后续我们会详细介绍-->
  14. <p>用户名:<input type="text" name="name"></p>
  15. <p>年龄:<input type="text" name="age"></p>
  16. <p>
  17. 爱好:
  18. <input type="checkbox" name="hobbies" value="music">音乐
  19. <input type="checkbox" name="hobbies" value="read">阅读
  20. <input type="checkbox" name="hobbies" value="dancing">跳舞
  21. </p>
  22. <p><input type="submit" value="提交"></p>
  23. </form>
  24. </body>
  25. </html>

2.2、HttpRequest对象常用属性part2

  1. 一.HttpRequest.body
  2. 当浏览器基于http协议的POST方法提交数据时,数据会被放到请求体中发送给djangodjango会将接收到的请求体数据存放于HttpRequest.body属性中,因为该属性的值为Bytes类型,所以通常情况下直接处理Bytes、并从中提取有用数据的操作是复杂而繁琐的,好在django会对它做进一步的处理与封装以便我们更为方便地提取数据,比如
  3. 对于form表单来说,提交数据的常用方法为GETPOST
  4. 1:如果表单属性method='GET',那么在提交表单时,表单内数据不会存放于请求体中,而是会将表单数据按照k1=v1&k2=v2&k3=v3的格式放到url中,然后发送给djangodjango会将这些数据封装到request.GET中,注意此时的request.body为空、无用
  5. 2:如果表单属性method='POST',那么在提交表单时,表单内的所有数据都会存放于请求体中,在发送给django后会封装到request.body里,此时django为了方便我们提取数据,会request.body的数据进行进一步的处理,具体如何处理呢,需要从form表单提交数据的编码格式说起:
  6. form表单对提交的表单数据有两种常用的编码格式,可以通过属性enctype进行设置,如下
  7. 编码格式1(默认的编码格式):enctype="application/x-www-form-urlencoded"
  8. 编码格式2(使用form表单上传文件时只能用该编码):enctype="multipart/form-data"
  9. 如果form表单提交数据是按照编码格式1,那么request.body中数据的格式类似于GET方法的数据格式,如k1=v1&k2=v2,此时django会将request.body中的数据提取出来封装到request.POST中方便我们提取
  10. 如果form表单提交数据是按照编码格式2,那么request.body中数据的格式为b'------WebKitFormBoundaryKtcwuksQltpNprep\r\nContent-Disposition: form-data;......',,此时django会将request.body中的数据提取出来封装到request.POST中,将上传的文件数据专门提取出来封装到request.FILES属性中
  11. 强调:毫无疑问,编码格式2的数据量要大于编码格式1,如果无需上传文件,还是推荐使用更为精简的编码格式1
  12. 我们除了可以采用form表单向django提交数据外,还可以采用ajax技术,ajax可以提交的数据格式有:1、编码格式1 2、编码格式2 3json,当ajax采用POST方法提交前两种格式的数据时,django的处理方案同上,但是当ajax采用POST方法提交json格式的数据时,django会将接收到的数据存放于HttpRequest.body,此时需要我们自己对HttpRequest.body属性值做反序列化操作,
  13. 具体的,我们在讲解ajax时再做具体介绍
  14. 二.HttpRequest.FILES
  15. 如果使用form表单POST上传文件的话,文件数据将包含在HttpRequest.FILES属性中。
  16.   该属性值为一个类似于字典的对象,可以包含多组key:value(对应多个上传的文件),其中每个key为<input type="file" name="" /> name属性的值,而value则为对应的文件数据
  17.   强调:HttpRequest.FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象。

案例:form表单上传文件

urls.py

  1. from django.urls import path,register_converter,re_path
  2. from app01 import views
  3. urlpatterns = [
  4. re_path(r'^register/$',views.register),
  5. ]

views.py

  1. from django.shortcuts import render,HttpResponse
  2. def register(request):
  3. if request.method == 'GET':
  4. return render(request,'register.html')
  5. elif request.method == 'POST':
  6. print(request.body)
  7. # 从request.POST中获取用户名
  8. name=request.POST.get('name')
  9. # 从request.FILES获取文件对象
  10. file_obj=request.FILES.get('header_img')
  11. # 上传的文件存放于templates文件夹下
  12. with open('templates/header.png','wb') as f:
  13. for line in file_obj:
  14. f.write(line)
  15. return HttpResponse('注册成功')

在templates目录下新建register.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>注册页面</title>
  6. </head>
  7. <body>
  8. <form action="" method="POST" enctype="multipart/form-data" >
  9. {% csrf_token %}
  10. <p>
  11. 用户名:<input type="text" name="name">
  12. </p>
  13. <p>
  14. 头像:<input type="file" name="header_img">
  15. </p>
  16. <p>
  17. <input type="submit" value="提交">
  18. </p>
  19. </form>
  20. </body>
  21. </html>

2.3、HttpRequest对象常用属性part3

  1. 一.HttpRequest.path
  2.   获取url地址的路径部分,只包含路径部分
  3. 二.HttpRequest.get_full_path()
  4.   获取url地址的完整path,既包含路径又包含参数部分
  5. 如果请求地址是http://127.0.0.1:8001/order/?name=egon&age=10#_label3,
  6. HttpRequest.path的值为"/order/"
  7. HttpRequest.get_full_path()的值为"/order/?name=egon&age=10"

案例:

urls.py

  1. from django.urls import path,register_converter,re_path
  2. from app01 import views
  3. urlpatterns = [
  4. re_path(r'^order',views.order),
  5. ]

views.py

  1. from django.shortcuts import render,HttpResponse
  2. # 针对请求的url地址:http://127.0.0.1:8001/order/?name=egon&age=10#_label3
  3. # 从域名后的最后一个“/”开始到“?”为止是路径部分,即/order/
  4. # 从“?”开始到“#”为止之间的部分为参数部分,即name=egon&age=10
  5. def order(request):
  6. print(request.path) # 结果为“/order/”
  7. print(request.get_full_path()) # 结果为"/order/?name=egon&age=10"
  8. return HttpResponse('order page')

2.4、HttpRequest对象常用属性part4

  1. 一.HttpRequest.META
  2.   值为包含了HTTP协议的请求头数据的Python字典,字典中的key及期对应值的解释如下
  3. CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
  4. CONTENT_TYPE —— 请求的正文的MIME类型。
  5. HTTP_ACCEPT —— 响应可接收的Content-Type
  6. HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
  7. HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
  8. HTTP_HOST —— 客服端发送数据的目标主机与端口
  9. HTTP_REFERER —— Referring 页面。
  10. HTTP_USER_AGENT —— 客户端使用的软件版本信息
  11. QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
  12. REMOTE_ADDR —— 客户端的IP地址。
  13. REMOTE_HOST —— 客户端的主机名。
  14. REMOTE_USER —— 服务器认证后的用户。
  15. REQUEST_METHOD —— 一个字符串,例如"GET" "POST"
  16. SERVER_NAME —— 服务器的主机名。
  17. SERVER_PORT —— 服务器的端口(是一个字符串)。
  18.   从上面可以看到,除 CONTENT_LENGTH CONTENT_TYPE 之外,HTTP协议的请求头数据转换为 META 的键时,
  19. 都会
  20. 1、将所有字母大写
  21. 2、将单词的连接符替换为下划线
  22. 3、加上前缀HTTP_
  23. 所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
  24. 注意:下述常用属性暂且了解即可,待我们讲到专门的知识点时再专门详细讲解
  25. 二.HttpRequest.COOKIES
  26.   一个标准的Python 字典,包含所有的cookie。键和值都为字符串。
  27. 三.HttpRequest.session
  28.  一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。
  29. 11.HttpRequest.user(用户认证组件下使用)
  30.   一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户。
  31. 2.HttpRequest.is_ajax()
  32.   如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串'XMLHttpRequest'
  33.   大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 可以工作。
  34.   如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django cache middleware
  35. 你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存。

三 响应对象(HttpResponse)

响应可以是任何形式的内容,比如一个HTML文件的内容,一个重定向,一个404错误,一个XML文档,或者一张图片等。总之,无论视图本身包含什么逻辑,都要返回响应,具体的说,响应对象主要有三种形式:HttpResponse,render,redirect

  1. from django.shortcuts import HttpResponse,render,redirect

3.1、HttpResponse()

括号内直接跟一个具体的字符串作为响应体,比较直接很简单,所以这里主要介绍后面两种形式。

3.2、render()

  1. render(request, template_name[, context])
  2. 参数:
  3. 1request:用于生成响应的请求对象,固定必须传入的第一个参数
  4. 2template_name:要使用的模板的完整名称,必须传入,render默认会去templates目录下查找模板文件
  5. 3context:可选参数,可以传入一个字典用来替换模块文件中的变量
  6. 综上,render的功能可以总结为:根据给定字典渲染模板文件,并返回一个渲染后的 HttpResponse对象。

3.3、redirect()

  1. # 返回重定向信息
  2. def my_view(request):
  3. ...
  4. return redirect('/some/url/')
  5. # 重定向的地址也可以是一个完整的URL:
  6. def my_view(request):
  7. ...
  8. return redirect('http://www.baidu.com/') 

重定向转态码301与302的区别(了解)

  1. 一、301302的异同。
  2. 1、相同之处:
  3. 301302状态码都表示重定向,具体点说就是浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址(浏览器会从响应头Location中获取新地址),用户看到的效果都是输入地址A后瞬间跳转到了另一个地址B
  4. 2、不同之处:
  5.   301表示旧地址A的资源已经被永久地移除了,即这个资源不可访问了。搜索引擎在抓取新内容的同时也将旧的网址转换为重定向之后的地址;
  6.   302表示旧地址A的资源还在,即这个资源仍然可以访问,这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容、并且会保存旧的网址。 SEO层面考虑,302要好于301
  7. 二、重定向原因:
  8. 1、网站调整(如改变网页目录结构);
  9. 2、网页被移到一个新地址;
  10. 3、网页扩展名改变(如应用需要把.php改成.Html或.shtml)。
  11. 这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。

四 JsonResponse

向前端返回一个json格式字符串的两种方式

方式一:

  1. import json
  2. def my_view(request):
  3. data=['egon','kevin']
  4. return HttpResponse(json.dumps(data) )

方式二:

  1. from django.http import JsonResponse
  2. def my_view(request):
  3. data=['egon','kevin']
  4. return JsonResponse(data,safe=False)
  5. #默认safe=True代表只能序列化字典对象,safe=False代表可以序列化字典以外的对象

五 FBV和CBV

django的视图层由两种形式构成:FBV和CBV

1、FBV基于函数的视图(Function base view),我们之前一直介绍的都是FBV

2、CBV基于类的视图(Class base view)

案例:

urls.py

  1. from django.urls import path,register_converter,re_path
  2. from app01 import views
  3. urlpatterns = [
  4. re_path(r'^login/',views.LoginView.as_view()), # 必须调用类下的方法as_view
  5. ]

views.py

  1. from django.shortcuts import render,HttpResponse,redirect
  2. from django.views import View
  3. class LoginView(View):
  4. def dispatch(self, request, *args, **kwargs): # 可在该方法内做一些预处理操作
  5. # 当请求url为:http://127.0.0.1:8008/login/会先触发dispatch的执行
  6. # 如果http协议的请求方法为GET,则调用下述get方法
  7. # 如果http协议的请求方法为POST,则调用下述post方法
  8. obj=super().dispatch(request, *args, **kwargs) # 必须继承父类的dispatch功能
  9. return obj # 必须返回obj
  10. def get(self,request):
  11. return render(request,'login.html')
  12. def post(self,request):
  13. name=request.POST.get('name')
  14. pwd=request.POST.get('pwd')
  15. if name == 'egon' and pwd == '123':
  16. res='登录成功'
  17. else:
  18. res='用户名或密码错误'
  19. return HttpResponse(res)

测试:

  1. python manage.py runserver 8001
  2. # 验证GET请求:在浏览器输入:http://127.0.0.1:8001/login/
  3. # 验证POST请求:在表单内输入数据然后提交

采用CBV可以引入面向对象的思想对数据进行更高程度的封装,此处简单了解即可,我们将在后续的项目中详细介绍它的应用于强大之处。

4、Django之视图层的更多相关文章

  1. 03-01 Django之视图层

    Django之视图层 一 视图函数 视图函数,简称视图,属于Django的视图层,默认定义在views.py文件中,是用来处理web请求信息以及返回响应信息的函数,所以研究视图函数只需熟练掌握两个对象 ...

  2. python 全栈开发,Day69(Django的视图层,Django的模板层)

    昨日内容回顾 相关命令: 1 创建项目 django-admin startproject 项目名称 2 创建应用 python manage.py startapp app名称 3 启动项目 pyt ...

  3. Django框架(四) Django之视图层

    视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...

  4. 6 Django 的视图层

    视图函数 一个视图函数,简称视图,是一个简单的 Python 函数,它接受 Web 请求并且返回 Web 响应.响应可以是一张网页的 HTML 内容,一个重定向,一个 404 错误,一个 XML 文档 ...

  5. 关于Django的视图层

    视图函数 通俗来讲:视图函数是在url配置是所匹配好了将要调用的对应函数(逻辑代码)        是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容 ...

  6. 6 Django的视图层

    视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...

  7. Django之路——4 Django的视图层

    一个视图函数简称称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何 ...

  8. Django之视图层

    一.视图函数 一个视图函数,简称视图,是一个简单的python函数,接收web请求并返回web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误等.在函数中必须写一个request的参 ...

  9. Django 的视图层

    什么是视图: 之前我们也了解了urls路由 那么路由的主要作用是决定你下一步走哪个视图函数 ,视图就是用来存放一个个的函数的python文件,主要存储的函数就是你Django主要的流程的控制 都存放在 ...

随机推荐

  1. 【题解】PTA-Little Bird

    Link 单调队列板子. 题目大意:一个点可以由距离它不超过\(k\)的点跳过来,如果那个点比它高就不需要花费体力,否则花费\(1\)的体力.问走到\(n\)的最小体力,多组询问. 显然的转移方程,设 ...

  2. .NET Standard 系列

    .NET Standard 是一套正式的 .NET API 规范,有望在所有 .NET 实现中推出. 推出 .NET Standard 的背后动机是要提高 .NET 生态系统中的一致性. ECMA 3 ...

  3. Word云(标签云)生成器控件。net Windows。形式在c#中

    下载demo - 37.1 KB 下载source code - 48.7 KB 背景 这种控制方式的灵感来自于一种名为Wordle的基于网络的免费单词云生成器.实际上,这个控件是我的项目http:/ ...

  4. 用cmd下载tp5.0版本

    1.首先进入phpstudy的www目录 composer create-project topthink/think=5.0.* pt5.0的名字 --prefer-dist $ composer ...

  5. 扩展、接管MVC都不会,还会用Spring Boot?

    持续原创输出,点击上方蓝字关注我 目录 前言 Spring Boot 版本 如何扩展MVC? 如何自定义一个拦截器? 什么都不配置为什么依然能运行MVC相关的功能? 如何全面接管MVC?[不推荐] 为 ...

  6. 多测师_肖sir_git _004(版本控制器)

    gitgit 是一个开源的分布式版本控制系统,用于敏捷高效的处理任何大小的项目.git是linux torvalds 为了帮助管理linux内核开发的一个开放源码的版本控制软件.git与常用的版本控制 ...

  7. MeteoInfoLab脚本示例:MERRA HDF数据

    MERRA是NOAA的一种再分析资料,HDF数据遵循COARDS协议,读取比较简单.脚本程序: #Add data file folder = 'D:/Temp/hdf/' fns = 'MERRA3 ...

  8. C++虚函数与多继承

    虚函数 C++用虚函数实现运行时多态,虚函数的实现是由两个部分组成的,虚函数指针与虚函数表. 虚函数指针(vptr)是指向虚函数表的指针,在一个被实例化的对象中,它总是被存放在该对象的地址首位.而虚函 ...

  9. pytest文档50-命令行参数--durations统计用例运行时间

    前言 写完一个项目的自动化用例之后,发现有些用例运行较慢,影响整体的用例运行速度,于是领导说找出运行慢的那几个用例优化下. --durations 参数可以统计出每个用例运行的时间,对用例的时间做个排 ...

  10. vm虚拟机设置共享文件夹不显示

    1. 确认VMtools已经装好,开启共享文件夹,设置好共享目录 2.执行命令 sudo mount -t vmhgfs .host:/ /mnt/hgfs如果出现错误: Error: cannot ...