Django入门03——Django模板

Django模板Templates

一、模板templates介绍

在Django框架中,模板时可以帮助开发者快速生成呈现给用户页面的工具。

模板的设计方式实现了我们MVT中VT的解耦(M:Model,V:View,T:Tempalates),VT有着N:M的关系,一个V可以调用任何T,一个T可以供任意V使用。

模板的处理可以分为两个过程:

  • 加载HTML
  • 渲染数据 render()

模板主要有两部分:

  • HTML静态代码
  • 模板语言,动态插入的代码段(挖坑、填坑) {{ var }}

模板中的动态代码段除了做基本的静态填充,还可以实现一些基本运算、转换和逻辑。

静态页面:页面数据是本地固定的
动态页面:页面数据来源于后台服务器

模板中的变量:视图函数传递给模板的数据,遵守标识符规则

  • 语法:{{ var }} ,如果变量不存在,则插入空字符串。
  • 方法不能有参数(方法后不能加小括号)
    {{ str }}
    {{ str.upper }}
    {{ str.isdigit }}
    {{ dict.key }}

模板中的列表
使用索引,不允许负索引
items = [‘apples’,‘bananas’,‘carrots’]
{{ items.2 }}

模板中的标签

  • 语法:{% tag %}
  • 作用:
    1.加载外部传入的变量
    2.在输出中创建文本
    3.控制循环或逻辑

模板中的if语句:

  • 格式:
    • if 单分支
      {% if 表达式 %}
      语句
      {% endif %}
    • if双分支
      {% if 表达式 %}
      语句
      {% else %}
      语句
      {% endif %}
    • if多分支
      {% if 表达式 %}
      语句
      {% elif 表达式%}
      语句
      {% else %}
      语句
      {% endif %}
  • 判断true或false
{% if today_is_weekend %}
	<p>Welcome to the weekend.p>
{% endif%}
  • 使用and or not
{% if athlete_list and coach_list %}
	<p>Both athletes and coachs are avaliable.p>
{% endif %}

{% if not athlete_list %}
	<p>There are not athletes.p>2
{% endif %}

{% if athlete_list or coach_list %}
	<p>There are some athletes or some coachs.p>
{% endif %}
  • 使用 in 和 not in
{% if 'bc' in 'abcdef'%}
	This appears since 'bc' is a substring of 'abcdef'
{% endif %}

{% if user not in users%}
	If users is a list,this will not appear if user isn't an element of the list.
{% endif %}

模板中的for语句:

  • 格式
    {% for 变量 in 列表%}
    语句1
    {% empty %}
    语句2
    {% endfor %}

    当列表为空或者不存在时,执行empty之后的语句。

  • {{ forloop.counter }} 表示当前是第几次循环,从1开始数

	{% for item in todo_list %}
		<p>{{ forloop.counter }}:{{ item }}p>
	{% endfor %}
	```
{{ forloop.counter0 }} 表示当前是第几次循环,从0开始数
{{ forloop.revcounter }}表示当前是第几次循环,倒着数,到1停
{{ forloop.revcounter0 }}表示当前是第几次循环,倒着数,到0停
{{ forloop.first }} 是否是第一个( 布尔值True或者False)

```html
{% for object in objects %}
	{% if forloop.first %}
		<li class="first">
	{% else %}
		<li>
	{% endif %}
	{{ object }}li>
{% endfor %}

{{ forloop.last }} 是否是最后一个( 布尔值True或者False)

{% for link in links %}
	{{ link }}{% if not loop.last %} | {% endif %}
{% endfor %}

forloop.parentloop

{% for country in countries %}
	<table>
		{% for city in country.city_list %}
		<tr>
			<td>Country #{{ forloop.parentloop.counter }}td>
			<td>City #{{ forloop.counter }}td>
			<td>{{ city }}td>
		tr>
	table>
{% endfor %}		
  • 注释:

    • 单行注释
      {# 被注释的内容 #}
    • 多行注释
      {% comment %}
      内容
      {% endcomment %}
  • 过滤器
    {{ var|过滤器 }}
    作用:在变量显示前修改

    add {{ var|add:2}}
    没有减法过滤器,但是加法里可以加负数
    {{ var|add:-2}}

    lower(将字母变成小写字母)
    {{ name|lower }}

    upper(将字母变成大写字母)
    {{ my_list|first|upper }}

    截断
    {{ bio|truncatechars:30 }}

    过滤器可以传递参数,参数需要使用引号引起来
    比如join:{{ students|join:‘=’ }}

    默认值:default,格式{{ var|default:value}}
    如果变量没有被提供或者为False、空,会使用默认值。

    根据指定格式转换日期为字符串,处理时间的,就是针对date进行的转换
    {{ dateVal | date:‘y-m’d’ }}

  • HTML转义
    将接收到的数据当成普通字符串处理还是当成HTML代码来渲染的一个问题。

    • 渲染成HTML:
      {{ code|safe }}
    • 关闭自动转义
      {% autoescape off %}
      code
      {% endautoescape %}
    • 打开自动转义
      {% autoescape on %}
      code
      {% endautoescape %}
  • 模板继承

    • block:
      {% block XXX %}
      code
      {% endblock %}

    • extends继承,写在开头位置
      {% extends ‘父模板路径’ %}

    • include:加载模板进行渲染
      {% include ’ 模板文件’ %}

    • {{ block.super }}:获取父模板中block中的内容

二、模板语法——变量

首先定义一个用于测试的视图函数:
render中传递的数据必须是字典格式,data是字典格式,所以可以直接将data传递过去。如果不是字典类型的数据,如data=[1,2,3],那么在传递数据时需要写成字典格式,即该数据作为value,还要给它一个key,{‘data’:data}。

# 模板测试函数
def model_test(request):
    data = {
        'name':'zhangsan',
        'age':30,
        'likes':['movie','game','code'],
        'address':{'city':'深圳','province':'广东'},
        'stars':[
            ['周杰伦','林俊杰','王力宏','伍佰'],
            ['张韶涵','张靓颖','杨丞琳','萨顶顶'],
            ['李荣浩','薛之谦','许嵩','汪苏泷']
        ],
    }
    # render传给模板的数据是一个字典,data是一个字典
    return render(request,'modeltest.html',data)

在跟路由下写上其路径:

path('modeltest/',model_test),

模板文件modeltest.html:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django模板title>
head>
<body>
    <h2>Django模板h2>
    <hr>
    {# 单行注释 #}
    {% comment %}
    多行注释
    多行注释内容
    {% endcomment %}

    {#  变量的使用  #}
    <p>name:{{ name }}p>
    <p>age:{{ age }}p>
    <p>likes:{{ likes }}p>
    <p>likes.2:{{ likes.2 }}p>
    <p>address:{{ address }}p>
    <p>address.city:{{ address.city}}p>
    <p>address.province:{{ address.province }}p>
    <hr>
body>
html>

访问页面:
Django入门03——Django模板_第1张图片

三、模板语法——标签

3.1 if语句

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django模板title>
head>
<body>
    <h2>Django模板h2>
    <hr>
    {# 单行注释 #}
    {% comment %}
    多行注释
    多行注释内容
    {% endcomment %}

{#  变量的使用  #}
    <p>name:{{ name }}p>
    <p>age:{{ age }}p>
    <p>likes:{{ likes }}p>
    <p>likes.2:{{ likes.2 }}p>
    <p>address:{{ address }}p>
    <p>address.city:{{ address.city}}p>
    <p>address.province:{{ address.province }}p>
    <hr>

{#  标签  #}
    <h2>if语句h2>
    <h4>单分支if语句h4>
    {% if age >= 18 %}
    	<p>{{ name }} 已经成年p>
    {% endif %}

    <h4>双分支if语句h4>
    {% if age >= 18 %}
    	<p>{{ name }} 已经成年p>
    {% else %}
        <p>{{ name }} 未成年p>
    {% endif %}

    <h4>多分支if语句h4>
    {% if age < 18 %}
    	<p>{{ name }} 未成年p>
    {% elif age < 60 %}
        <p>{{ name }} 是壮年p>
    {% else %}
        <p>{{ name }} 是老年p>
    {% endif %}


    <h4>结合运算符h4>
    {% if age >= 18 and age <= 60 %}
        <p>{{ name }} 是壮年,风华正茂p>
    {% endif %}
    {% if age < 18 or age > 60 %}
        <p>{{ name }} 是未成年或者老年人p>
    {% endif %}

    {#  in和not in  #}
    {% if 'movie' in likes %}
    	<p>{{ name }} 喜欢moviep>
    {% endif %}
{#  br标签可以给页面添加滚动栏  #}
    <br><br><br><br><br><br>
    <br><br><br><br><br><br>
    <br><br><br><br><br><br>

body>
html>

3.2 for语句

forloop表示当前循环,forloop.parentloop表示当前循环的父循环,即当前循环的上一层循环。

 <hr>
<h3>for循环语句h3>
{% for like in likes %}
    <p>爱好:{{ like }}p>
{% endfor %}

页面效果:
Django入门03——Django模板_第2张图片
for循环中empty的用法:如果被遍历的数据容器是空的或者无法被遍历的,就不会执行for循环中的语句。
likes2并不存在,所以就会执行empty下的语句。

<h4>empty的用法:如果被遍历的数据容器是空的或者无法被遍历的,就不会执行for循环中的语句h4>
{% for like in likes2 %}
    <p>爱好:{{ like }}p>
{% empty %}
    <p>likes2为空或者不存在p>
{% endfor %}

页面效果:
在这里插入图片描述

for循环语句中下标的使用,counter0表示每一条循环语句的下标从0开始数;counter表示每一条循环语句的下标从1开始数;revcounter0表示每一条循环语句的下标倒着数,到0结束,即最后一条循环语句的下标是0;revcounter表示每一条循环语句的下标倒着数,到1结束,即最后一条循环语句的下标是1。

.first 会标记出循环语句第一次执行的结果,.last会标记出循环语句最后一次执行的结果。

<h4>下标h4>
{% for like in likes %}
    <p>
    	counter0:{{ forloop.counter0 }},
        counter:{{ forloop.counter }},
        revcounter0:{{ forloop.revcounter0 }},
        revcounter:{{ forloop.revcounter }},

        {# 判断是否是第一条循环语句和判断是否是最后一条循环语句#}
        {% if forloop.first %}
            <b> - first b>
        {% endif %}

        {% if forloop.last %}
            <b> - last b>
        {% endif %}
    p>
{% endfor %}

嵌套循环:

for循环语句中可以嵌套for循环,也可以嵌套if语句。通过嵌套循环和表格来展示嵌套列表stars中的数据。table标签表示创建一个表格,其样式可以通过标签属性来设置。tr标签表示表格的每一行,td标签表示每一个单元格。通过嵌套循环遍历表格的每一行,再遍历每一行中的每一个单元格。

 <h4>循环嵌套h4>
{#  表格标签table,border显示表格边框,宽度width为300  #}
<table border="1" width="300">
   {#    遍历表格的每一行,每一个tr标签表示表格的一行    #}
   {% for star in stars %}
        <tr>
            {#  遍历表格一行的每一个单元格,td标签表示一个单元格 #}
            {% for s in star %}
                <td>
                   {{ s }}
                td>
            {% endfor %}

        tr>
   {% endfor %}

table>

页面效果:
Django入门03——Django模板_第3张图片
也可以给第一层循环的每次循环添加下标:

 <h4>循环嵌套h4>
    {#  表格标签table,border显示表格边框,宽度width为300  #}
    <table border="1" width="500">
        {#    遍历表格的每一行,每一个tr标签表示表格的一行    #}
        {% for star in stars %}
        	<tr>
                {#  遍历表格一行的每一个单元格,td标签表示一个单元格 #}
                {% for s in star %}
                	<td>
                        {{ s }} - 
                        {# forloop表示当前循环,parentloop表示父循环,forloop.parentloop表示当前循环的父循环,即上一层循环  #}
                        {# counter表示从1开始数的下标,即给上一层循环的每一循环都添加下标,从1开始数 #}
                        {{ forloop.parentloop.counter }}
                    td>
                {% endfor %}

            tr>
        {% endfor %}

    table>

页面效果:
Django入门03——Django模板_第4张图片
forloop.counter表示当前循环的下标,从1开始数,当前循环遍历一行的每一个单元格。
Django入门03——Django模板_第5张图片

{% for s in star %}
	<td>
		{{ s }} -
        {# forloop表示当前循环,parentloop表示父循环,forloop.parentloop表示当前循环的父循环,即上一层循环  #}
        {# counter表示从1开始数的下标,即给上一层循环的每一循环都添加下标,从1开始数 #}
        {{ forloop.parentloop.counter }} -
        {{ forloop.counter }}

   td>
{% endfor %}

页面效果:
第一个数字表示第一层循环的下标,第二个数字表示第二层循环的下标。
Django入门03——Django模板_第6张图片

四、模板语法——过滤器

使用过滤器进行运算:

<hr>
<h4>过滤器h4>
<p>age = {{ age }}p>
{#  使用过滤器进行加法:add表示+  #}
<p>age = {{ age | add:2 }}p>
{#  若是要进行减法,可以加上负数  #}
<p>age = {{ age | add:-2 }}p>

页面效果:
Django入门03——Django模板_第7张图片

<p>name = {{ name }}p>
{#  将名字的第一个字母变成大写  #}
<p>name|first|upper = {{ name|first|upper }}p>
{# 将名字中的字母都变成大写 #}
<p>name|upper = {{ name|upper }}p>
{# 截断字符串 #}
<p>name|truncatechars:4 = {{ name|truncatechars:4 }}p>

页面效果:
Django入门03——Django模板_第8张图片
字符串拼接:

{# 字符串拼接 #}
<p>likes = {{ likes }}p>
<p>likes|join:'+'= {{ likes|join:'+' }}p>

页面效果:
Django入门03——Django模板_第9张图片
显示日期:
在视图函数model_test()的data中添加:

'dt':datetime.datetime.now(),

模板文件中:

{# 显示日期 #}
<p>dt = {{ dt }}p>
<p>dt = {{ dt|date:'y-m-d' }}p>
<p>dt = {{ dt|date:'Y-m-d' }}p>

页面效果:
y-m-d中,y表示年份的后两位数字,m表示月份,d表示天。大写Y可以显示完整的年份。
Django入门03——Django模板_第10张图片
HTML转义:
必须确保是安全的HTML标签才能使用safe进行解析。

在视图函数model_test()的data中添加:

# b标签表示加粗字体
'code':'I am a people',

模板文件中:

{# HTML转义 #}
<p>code = {{ code }}p>
<p>code|safe = {{ code|safe }}p>

页面效果:
b标签被解析,标签中的文本被加粗。
Django入门03——Django模板_第11张图片

五、模板语法——继承

{#  模板继承  #}
    {#  block方法是写在父模板中,block.super用于获取父模板中block的内容  #}
    {#  extend方法是写在子模板的开头位置,用来继承父模板  #}
    {#  include方法用于在模板中引入其他的模板文件  #}

创建视图函数:

# 模板继承视图函数
# 父模板
def block(request):
    return render(request,'block.html')
# 子模板
def child(request):
    return render(request,'child.html')

路由url:

path('block/', block),
path('child/', child),

模板:

block标签中的内容并不会在网页中显示。

  • block.html:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>

{#  css  #}
    {% block extcss %}

    {% endblock %}
head>
<body>
    <h2>父模板h2>
    <hr>

    {% block head %}

    {% endblock %}
    <hr>

    {% block content %}
        <button>我是父模板中的按钮Contentbutton>
    {% endblock %}
    <hr>

    {% block foot %}

    {% endblock %}
    <hr>
{#  JavaScript  #}
    {% block extjs %}

    {% endblock %}
body>
html>

页面效果:
Django入门03——Django模板_第12张图片

  • child.html:

子模板中不需要写head、body标签这些固定的东西。只需要使用block继承父模板就可以获得和父模板中一样的内容。但是,子模板的block标签中的内容默认会覆盖父模板中block标签的内容。比如在父模板content中的按钮并不会在子模板页面中显示,如果想要继承父模板block标签中的内容,需要使用block.super。

{#  子模板中不需要写这些固定的东西  #}
{#  继承父模板  #}
{#  继承之后子模板中的内容与父模板中内容一样  #}
{% extends 'block.html' %}

{% block head %}
	<div>
        <button>headbutton>
    div>
{% endblock %}

{% block content %}
{#  默认情况下,子模板会覆盖父模板的内容。如果想将父模板中block内容继承,则需要使用block.super #}
    {{ block.super }}
	<div>
        <button>contentbutton>
    div>
{% endblock %}

{% block foot %}
	<div>
        <button>footbutton>
    div>
{% endblock %}

页面效果:
Django入门03——Django模板_第13张图片

使用include方法导入其他模板中的内容。如果模板中内容太多,会显得杂乱,我们可以将部分内容放到其他模板文件中,使用时再用include方法从其他模板中导入。

创建一个child_include.html:

<ol>
    <li>床前明月光,疑是地上霜li>
    <li>黑云压城城欲摧,甲光向日金鳞开li>
    <li>沉舟侧畔千帆过,病树前头万木春li>
    <li>长风破浪会有时,直挂云帆济沧海li>
ol>

在child.html中使用include方法引用child_include.html中的内容:

{% block foot %}
	<div>
        <button>footbutton>
    div>

     {% 导入其他模板文件   %}
    {% include 'child_include.html' %}

{% endblock %}

页面效果:
Django入门03——Django模板_第14张图片

渲染render,利用的是模板语言,可以将变量、数据传进去,并且html内部可以使用大量的模板语法。渲染的作用就是将后端和前端绑定在一起。使用模板(HTML+模板语言)——前后端不分离

你可能感兴趣的:(django,sqlite,数据库)