视图函数与模版

mac2022-06-30  26

1.HttpRequest对象

  首先先要明确的是HttpRequest返回的是字符串格式的,在view函数中的request是他们所要返回的数据,那么我们先看一看request常用的属性:

  1.HttpRequest.GET 包含所有的GET请求的所有参数

  2.HttpRequest.POST  顾名思义返回的是post请求的所有参数

  3.HttpRequest.path  返回的是请求路径组件(不包含域名)

  4.HttpRequest.method  返回是请求http方式

  5.HttpRequest.META 返回的是所有Http首部的所有信息

/* 1.HttpRequest.GET   一个类似于字典的对象,包含 HTTP GET 的所有参数。详情请参考 QueryDict 对象。 2.HttpRequest.POST   一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成 QueryDict 对象。   POST 请求可以带有空的 POST 字典 —— 如果通过 HTTP POST 方法发送一个表单,但是表单中没有任何的数据,QueryDict 对象依然会被创建。 因此,不应该使用 if request.POST 来检查使用的是否是POST 方法;应该使用 if request.method == "POST"   另外:如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中。 注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用: request.POST.getlist("hobby") 3.HttpRequest.body   一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等。   但是,如果要处理表单数据的时候,推荐还是使用 HttpRequest.POST 。 4.HttpRequest.path   一个字符串,表示请求的路径组件(不含域名)。   例如:"/music/bands/the_beatles/" 5.HttpRequest.method   一个字符串,表示请求使用的HTTP 方法。必须使用大写。   例如:"GET"、"POST" 6.HttpRequest.encoding   一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。 这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。 接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。 如果你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。 7.HttpRequest.META   一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例: CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。 CONTENT_TYPE —— 请求的正文的MIME 类型。 HTTP_ACCEPT —— 响应可接收的Content-Type。 HTTP_ACCEPT_ENCODING —— 响应可接收的编码。 HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。 HTTP_HOST —— 客服端发送的HTTP Host 头部。 HTTP_REFERER —— Referring 页面。 HTTP_USER_AGENT —— 客户端的user-agent 字符串。 QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。 REMOTE_ADDR —— 客户端的IP 地址。 REMOTE_HOST —— 客户端的主机名。 REMOTE_USER —— 服务器认证后的用户。 REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。 SERVER_NAME —— 服务器的主机名。 SERVER_PORT —— 服务器的端口(是一个字符串)。   从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时, 都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。 所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。 8.HttpRequest.FILES   一个类似于字典的对象,包含所有的上传文件信息。 FILES 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据。   注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会 包含数据。否则,FILES 将为一个空的类似于字典的对象。 9.HttpRequest.COOKIES   一个标准的Python 字典,包含所有的cookie。键和值都为字符串。 10.HttpRequest.session   一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。 完整的细节参见会话的文档。 11.HttpRequest.user(用户认证组件下使用)   一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户。   如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们。 例如: if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users.   user 只有当Django 启用 AuthenticationMiddleware 中间件时才可用。 ------------------------------------------------------------------------------------- 匿名用户 class models.AnonymousUser django.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口,但具有下面几个不同点: id 永远为None。 username 永远为空字符串。 get_username() 永远返回空字符串。 is_staff 和 is_superuser 永远为False。 is_active 永远为 False。 groups 和 user_permissions 永远为空。 is_anonymous() 返回True 而不是False。 is_authenticated() 返回False 而不是True。 set_password()、check_password()、save() 和delete() 引发 NotImplementedError。 New in Django 1.8: 新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。 */ 十一种详细说明

  request的常用方法

/* 1.HttpRequest.get_full_path()   返回 path,如果可以将加上查询字符串。   例如:"/music/bands/the_beatles/?print=true" 2.HttpRequest.is_ajax()   如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串'XMLHttpRequest'。   大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 可以工作。   如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django 的 cache middleware, 你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存。 */

响应对象主要有三种形式:

HttpResponse()render()redirect()

第一种已经介绍过了,只要记住他返回的一个字符串格式就可以,还有可以返回那些request中的内容

2.render()

  也是一样要记住render() 返回的是一个页面  render(request,"xxxx.html"  ,{"xxx":xxx})

3.redirect()

  重定向,也就是这个会把你的页面返回到你需要跳转的页面那里

他是这样用的(个人理解):return redirect("/index/")硬编码 第二种就是别名但是要引入一个reserve模块写法  return redirect(reserve"别名")

扩充知识点所有返回的状态中301和302就是重定向的错误记住这些可以帮助我们快速的排错

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

 

4模板 (两个重点:1.{{   }}  2.{%  %})

  多的时候是搭配render里面穿过来的参数搭配使用的

4.1模板的过滤器

  1.default  按照单词去理解大致的意思就是默认值呗

写法:    {{ value|default:"nothing" }}    在html想要渲染的位置加上要默认值参数就可以   

   2.length  返回的是字符串的长度

写法:  {{ value|length }}

  3.filesizeformat  将值的格式化为人类可以可读的文件尺寸(例如 '13 KB', '4.1 MB', '102 bytes', 等等)

写法:  {{ value|filesizeformat }}

  4.data   返回的是时间的格式  一般是需要过滤的

写法:      去值的时候 value=datetime.datetime.now() 

    渲染的时候{{ value|date:"Y-m-d" }}

  5.silce  切片显示

写法:  取值时:value="hello world"

   渲染的时候:{{ value|slice:"2:-1" }}  按照你想要的方式切片去取

  6.truncatechars  如果现实的内容有太多但是我们只想让文章的前几个字显示,这个时候就要用到这个

写法:{{ value|truncatechars:9 }}显示三个文字,这里面的参数是按照你字节的需求去变得

  7.safe  Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。

  一句话总结为了防止恶意攻击做的

写法: 书写时 value="<a href="">点击</a>"

   渲染时  {{ value|safe}}

5.模板的标签

  重点说两个:for标签和csrf_token

  5.1for标签顾名思义就是用来做循环的举个例子

{% for person in person_list %} <p>{{ person.name }}</p> {% endfor %}

  5.2 csrf_token  用于跨站请求伪造保护的

其他:

for ... empty

for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。

{% for person in person_list %} <p>{{ person.name }}</p> {% empty %} <p>sorry,no person here</p> {% endfor %}

if 标签

{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

{% if num > 100 or num < 0 %} <p>无效</p> {% elif num > 80 and num < 100 %} <p>优秀</p> {% else %} <p>凑活吧</p> {% endif %}

with

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的

例如:

{% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %}

6.自定义模板

1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

2、在app中创建templatetags模块(模块名只能是templatetags)

3、创建任意 .py 文件,如:my_tags.py

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from  django  import  template from  django.utils.safestring  import  mark_safe   register  =  template.Library()    #register的名字是固定的,不可改变     @register . filter def  filter_multi(v1,v2):      return   v1  *  v2 <br> @register .simple_tag def  simple_tag_multi(v1,v2):      return   v1  *  v2 <br> @register .simple_tag def  my_input( id ,arg):      result  =  "<input type='text' id='%s' class='%s' />"  % ( id ,arg,)      return  mark_safe(result)

4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py

1 { %  load my_tags  % } 

5、使用simple_tag和filter(如何调用)

1 2 3 4 5 6 7 8 9 10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .html { %  load xxx  % }          # num=12 {{ num|filter_multi: 2  }}  #24   {{ num|filter_multi: "[22,333,4444]"  }}   { %  simple_tag_multi  2  5  % }  参数不限,但不能放在 if  for 语句中 { %  simple_tag_multi num  5  % }

注意:filter可以用在if等语句后,simple_tag不可以

1 2 3 { %  if  num|filter_multi: 30  >  100  % }      {{ num|filter_multi: 30  }} { %  endif  % }

7 模板继承 (extend)

为什么要说模板继承,主要是因为我们在写页面的时候会出现这种情况,多个页面的大多数地方都是一样的只要极个别的地方不一样,但是在写新页面的时候会把前面一样的地方都重复的全部写一般,这时候我们就可以用到继承,写一个基础的页面其他的页面继承他的写法做简单的修改,这样就减少了重复造车轮的做法

写法:就是在父类的页面需要有改变的地方加上{% block%}

  在子代需要继承的页面最前面写上这样一句话:{% extends "base.html" %}  然后在你需要改的加上要变化的地方

 

转载于:https://www.cnblogs.com/RootEvils/p/9832055.html

最新回复(0)