模板(template)

一、模板渲染

 

思考 : 网站如何向客户端返回一个漂亮的页面呢?

  • 提示 :

    • 漂亮的页面需要htmlcssjs.
    • 可以把这一堆字段串全都写到视图中, 作为HttpResponse()的参数,响应给客户端.
  • 问题 :

    • 视图部分代码臃肿, 耦合度高.
    • 这样定义的字符串是不会出任何效果和错误的.
    • 效果无法及时查看.有错也不容易及时发现.
  • 设想 :

    • 是否可以有一个专门定义前端页面的地方, 效果可以及时展示,错误可以及时发现,并且可以降低模块间耦合度!
  • 解决问题 :模板

    • MVT设计模式中的T,Template
  • Django中, 将前端的内容定义在模板中, 然后再把模板交给视图调用, 各种漂亮、炫酷的效果就出现

 

之前演示时使用 HttpResponse来进行测试字符串的返回

 

也介绍了HttpResponse有三种模式,那么如果我们要对界面渲染的将view中定义的元素展示到html界面的话 该怎么办呢?


1、1: render方法

render(请求template_name上下文=content_type=状态=使用=)

将给定模板与给定上下文字典组合在一起,并返回具有该呈现文本的 HttpResponse 对象。

Django 没有提供返回 TemplateResponse 的快捷方式函数,因为 TemplateResponse 的构造函数提供了与 render() 相同级别的便利性。

必需参数(指定你的 要渲染的html文件)

  

request:   用于生成此响应的请求对象。
template_name   : 要使用的模板的全名或模板名称的序列。如果给定了序列,则将使用存在的第一个模板。有关如何查找模板的详细信息,请参阅模板加载文档。

 

可选参数(渲染到html的元素)

  

context
要添加到模板上下文中的值的字典。默认情况下,这是一个空字典。如果字典中的某个值是可调用的,则视图将在呈现模板之前调用它。
content_type
用于生成的文档的 MIME 类型。缺省值为 。'text/html'
status
响应的状态代码。缺省值为 。200
using
用于加载模板的模板引擎的名称。

 

例如:我的工程叫book,有bookmanage和booktestone两个app

 

 

 

首先在工程同级目录建立一个testplate(用来存放前端文件),注意是工程同级别目录,而不是工程上一级目录,不然会找不到

 

 

 

在template下再建立对应的app目录,存放对应的app的前端文件

 

 

 

  • settings.py(添加前端模板位置):

    •   
      TEMPLATES = [
          {
              'BACKEND': 'django.template.backends.django.DjangoTemplates',
              'DIRS': [os.path.join(BASE_DIR, 'templates')],  # 配置模板位置
              'APP_DIRS': True,
              'OPTIONS': {
                  'context_processors': [
                      'django.template.context_processors.debug',
                      'django.template.context_processors.request',
                      'django.contrib.auth.context_processors.auth',
                      'django.contrib.messages.context_processors.messages',
                  ],
              },
          },
      ]

       

    • 可以把这一堆字段串全都写到视图中, 作为HttpResponse()的参数,响应给客户端.
  • booktestone/urls.py :

    •   
      from django.urls import path
      from django.urls import path,include
      from .views import index
      urlpatterns = [
          path('index/', index ),
      ]

       

  • booktestone/views.py
    •   
      from django.shortcuts import render
      
      from django.http import HttpResponse, HttpRequest
      # Create your views here.
      
      
      def index(request):
          context = {'name': '我是模板渲染的参数'}
          return render(request,"booktestone/index.html", context ) #指定渲染的模板并传递模板参数

       

       

  • template/index.html
  • 渲染是将传递的context中的内容渲染

    • <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
      
      This is booktestone/index<br/>
      
      {{ name }}  # 渲染取值是取context中的值
      
      </body>
      </html>

       

  • 前端访问展示
    •   

 

 

1.2例子

1.创建模板

  • 应用同级目录下创建模板文件夹templates. 文件夹名称固定写法.
  • templates文件夹下, 创建应用同名文件夹. 例, Book
  • 应用同名文件夹下创建网页模板文件. 例 :index.html

  •  

     

2.设置模板查找路径

 

 

3.模板接收视图传入的数据

视图模板加载

 

 

4.模板处理数据

 

 

5. 查看模板处理数据成果

 

 

 

 setting.py中得静态文件(图片之类得)

需要在setting.py中配置

# 告知静态文件在那里
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'目录名')
]

 

 

 

 

二、

 

错误之forbbiddon

csrf_token:这个标签用于跨站请求伪造保护

提交数据的时候就会做安全机制,当你点击提交的时候会出现一个forbbiddon
的错误,就是用setting配置里的scrf做安全机制的,那么我们可以吧它给注释了,,,
或者在form表单下面添加一个{% csrf_token %},,,
这才是真正解决的办法,注释不是解决的办法
<h3>scrf_token</h3><form action="/tag/" method="post">
    {% csrf_token %}
    <p><input type="text" name="haiyan"></p>
    <input type="submit">
</form>

模型层又是Django创建之初自带的文件夹 

里面是存放我们的HTML代码的 这样式为了便于维护 和增强解耦性

页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式

 

python的模板:HTML代码+模板语法

模版包括在使用时会被值替换掉的 变量,和控制模版逻辑的 标签。

模板之---------深度查询:

它的深度查询式根据 .来区别的

<h1>深度查询</h1>
<p>{{ name }}</p>
<p>{{ l }}</p>  {# 把views与之对应l显示在页面中#}
<p>{{ info }}</p>   {# 把views与之对应的info显示在页面#}
<p>{{ l.0 }}</p>    {#把l这个列表中的第一项显示出来 #}
<p>{{ l.1 }}</p>    {# 把l这个列表中的第二项显示出来#}
<p>{{ l.2 }}</p>   {# 把l对应的列表的第三项显示出来#}
<p>{{ info.name }}</p> {#把字典info对应的name显示在页面中#}

所以看出来 深度查询就是利用点来查找具体的深度的值

 

模板之---------过滤器:

模板语法之过滤器:语法 {{obj|filter__name:param}}

1、default:如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:

<p>default过滤器:{{ li|default:"如果显示为空,设置的解释性的内容" }}</p>

2、length:返回值的长度。它对字符串和列表都起作用。例如:

{{ value|length }}

如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。

3、filesizeformat:将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB''4.1 MB''102 bytes', 等等)。例如:

{{ value|filesizeformat }}

如果 value 是 123456789,输出将会是 117.7 MB。  

4、date:如果 value=datetime.datetime.now()

{{ value|date:"Y-m-d" }}  

5、slice  :切片

如果 value="hello world"

{{ value|slice:"2:-1" }}

6、truncatechars  截断

如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。

参数:要截断的字符数

例如:

<p>截断字符:{{ content|truncatechars:20 }}</p>
<p>截断单词:{{ content|truncatewords:4 }}</p>

如果content是“I am is haiyan,how are you asd df dfgfdgdg?

输出结果: 截断字符:I am is haiyan,ho...

输出结果 :截断单词:I am is haiyan,how ...

7、safe

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

value="<a href="">点击</a>"

{{ value|safe}}
<p>{{ label }}</p>  <!--为了安全系统会把标签变成字符串-->
<p>{{ label|safe }}</p>    <!--加上safe,确定你的数据是安全的才能被当成是标签-->

 

模板语法之标签:语法为 {% tag  %}:

标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。

一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})。

 

1、for标签(注:循环序号可以通过{{forloop}}显示)

{% for item in 迭代对象  %}
    判读语句
{% endfor %}


if判读 {
% if 条件 %} {% endif %}

 

 

 

for 语句

遍历每一个元素:

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

可以利用{% for obj in list reversed %}反向完成循环。

开始:
{% for   加判读条件%}


结束
{%enfor%}

 

{% for item in l %}
    {% if item > 100 %}
        <p>{{ item }}</p>
    {% endif %}
{% endfor  %}

上面是先循环视图内的l列表 当列表内的item是大于100的那就打印在浏览器上

 

{% for animal in animal_list  %}
<p>{{ animal.name }},{{ animal.age }}</p>
{% endfor  %}

这个是打印你的视图内的animal_list列表内的对象的各个名字和年龄

循环序号可以通过{{forloop}}显示

{% for fool in l %}
    <p>{{ forloop.counter }}:{{ fool }}</p>
{% endfor %}


就是把列表l的内容都循环输出 然后在它的开头给定义一个序列号 从1开始的序列号

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值),对应的内容块会输出。

其实和for语句差不多 都有开始 和结束 还有else

{% if animal.age > 30 %}
        <p>{{ animal.name }},{{ animal.age }}老年人</p>
    {% else %}
    <p>{{ animal.name }},{{ animal.age }}年轻人</p>
    {% endif %}

如果年龄大于30的就输出老年人 如果年龄小于30的就输出年轻人

 

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

其实就是起了一个别名

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}
<p>{{ person_list.2.name }}</p>
{% with name=person_list.2.name %}
    <p>{{ name }}</p>
{% endwith %}

 

 

{% with f_name=animal_list.0.name %}   
    <p>{{ f_name }}</p>  
{% endwith %}

给列表中的第一个name起一个别名

 

就是起别名

 

posted @ 2018-06-25 21:23  可爱的红领巾  阅读(491)  评论(0编辑  收藏  举报