zoukankan      html  css  js  c++  java
  • Django:模板template(一)

    把模板的过程、语法、标签、反向地址解析、过滤器、模板继承与HTML转义记下笔记

    1、概述及demo

    动态生成HTML

    模板的设计实现业务逻辑(View)和显示内容(template)的分离

    一个模板可以给多个视图去使用,模板所使用的语法称为DTLDjango Template Language)定义在django.template

    如果要调用模板,则需要如下步骤:

    1. 加载模板。通过loaderget_template方法指定一个模板
    2. 渲染模板。
      1.   指定一个上下文对象,RequestContext()
      2.   用模板的render()方法接收上下文对象。作为HttpResponse()的参数

    demo示例的过程:创建工程 - 添加数据库 - 创建应用 -  添加模板路径 - 设置路由 - 编写urls.py - 编辑视图 - 添加模板

    添加模板路径:修改settings.py配置,TEMPLATES中修改DIRS。指定TEMPLATES的目录

    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',
                ],
            },
        },

    添加模板:

    booktest/views.py

    from django.http import HttpResponse
    from django.template import loader, RequestContext
    def resp(request): t1 = loader.get_template('booktest/resp.html') context = RequestContext(request, {"text":"helloworld"}) return HttpResponse(t1.render(context))

    templates/booktest/resp.html

    <body>
    {{text}}
    </body>

    实际上上面的代码通过会被封装到一个函数render()中,所以我们一般简写为

    from django.shortcuts import render
    from django.http import HttpResponse
    
    def resp(request):
        context = {"text":"helloworld"}
        return render(request, "booktest/resp.html", context)

    2、模板语法

    • 变量。两个大括号括起来的 {{变量名}}
    • 标签。代码段 {% 代码块 %}
    • 过滤器。就是一个竖线(|
    • 注释。{# 这里是注释 #}

    变量

    模板碰到变量的时候,计算这个变量的值,然后将结果输出

    变量名有字母、数字、下划线组成。必须以字母或下划线开头

    当模板引擎碰到圆点的时候,会按照如下的顺序进行查询:

    1. 字典。把圆点前面的内容理解为一个字典,圆点后面的内容理解为键
    2. 属性或方法查询。把圆点前面的内容理解为一个对象,圆点后面的内容理解为对象里面的属性或方法(访问方法不能加括号,方法也不能定义参数)
    3. 数字索引查询。把圆点前面的内容理解为列表或元组。圆点后面的内容理解为下标(下标只能为数字,不能为字符串)

    比如访问{{book.id}},会按照如下顺序解析:

    1. book当做字典。访问book[‘id’],如果book字典中有id的键,则查询成功,并返回,如果没有id的键,或者甚至没有book字典,查询失败,往下
    2. book当做对象,把id当做属性或方法,尝试访问book.idbook.id()如果book对象中有id的属性或方法,则查询成功,调用并返回,否则往下
    3. book当做列表或元组,把id当做索引,访问book[id],如果访问成功,则输出,否则往下
    4. book.id作为空字符串’’来输出

     3、引入模型

    models.py中定义类HeroInfo

    booktest/models.py

    from django.db import models
    
    # Create your models here.
    class BookInfo(models.Model):
        btitle = models.CharField(max_length = 20)
        bpub_date = models.DateTimeField(db_column = 'pub_date')
        bread = models.IntegerField()
        bcomment = models.IntegerField()
        isDelete = models.BooleanField()
        class Meta():
            db_table = 'bookinfo'
        
    class HeroInfo(models.Model):
        hname = models.CharField(max_length = 10)
        hgender = models.BooleanField()
        hcontent = models.CharField(max_length = 1000)
        isDelete = models.BooleanField()
        book = models.ForeignKey('BookInfo', on_delete = models.CASCADE)
        def showname(self):
            return self.hname

    生成迁移,数据库中生成bookinfo和booktest_heroinfo的表

    >>>python manage.py makemigrations
    >>>python manage.py migrate

    bookherosql语句插入到数据库中

    修改视图类  booktest/views.py

    from django.shortcuts import render
    from booktest.models import BookInfo, HeroInfo
    
    # Create your views here.
    def index(request):
        hero = HeroInfo.objects.get(pk=1)
        context = {'hero': hero}
        return render(request, 'booktest/index.html', context)

    模型中,既可以访问属性,也可以访问方法(访问方法不能加括号)

    booktest/index.html

    <body>
        {{hero.hname}}
        {{hero.showname}}
    </body>

     

    4、使用标签

    语法:{% 标签 %}。注意标签中写的是代码

    作用:

    1. 在输出中创建文本
    2. 循环或条件判断等逻辑
    3. 加载外部信息

    for标签

    {% for ... in ... %}
    {{ forloop.counter }} 表示当前是第几次循环
    {% empty %}
    列表是空或不存在的时候,执行这里
    {% endfor %}

    修改views.py    booktest/views.py

    # Create your views here.
    def index(request):
        heroList = HeroInfo.objects.filter(isDelete=False)
        context = {'heroList': heroList}
        return render(request, 'booktest/index.html', context)

    模板的代码中添加for标签 templates/booktest/index.html

    <ul>
    {% for hero in heroList %}
    <li>{{ forloop.counter }}: {{hero.showname}}</li>
    {% empty %}
    <li>找不到</li>
    {% endfor %}
    </ul>

    if标签

    {% if ... %}
    逻辑1
    {% elif ... %}
    逻辑2
    {% else %}
    逻辑3
    {% endif %}

    比如,想奇数行显示红色,偶数行显示蓝色

    <ul>
    {% for hero in heroList %}
    
      {% if forloop.counter|divisibleby:"2" %}
      <li style="color:red">{{ forloop.counter }}: {{hero.showname}}</li>
      {% else %}
      <li style="color:blue">{{ forloop.counter }}: {{hero.showname}}</li>
      {% endif %}
    
    {% empty %}
    <li>找不到</li>
    {% endfor %}
    </ul>

    4、反向地址解释

    {% url name p1 p2 ... %}

    先创建一个页面

    路由: booktest/urls.py

    urlpatterns = [
        url('^$',views.index), # 路由到views.py中的index()函数
        url('^(d+)$',views.show),
    ] 

    视图: booktest/views.py

    urlpatterns = [
        url('^$',views.index), # 路由到views.py中的index()函数
        url('^(d+)$',views.show),
    ] 

    模板:templates/booktest/show.html

    <body>
        {{id}}
    </body>

     

    接下来考虑在index中,添加一个链接,点击后可以跳转到123一般是这样写

    <a href="/booktest/123">跳转</a>

    但是万一路由被改变了

    urlpatterns = [
        url(r'^admin/', include(admin.site.urls)),
        url('booktest1/', include('booktest.urls'))
    ]

    此时,链接的地址就发生了改变。如果要随时去修改链接的地址,就有点麻烦了

    因此考虑使用地址的反向解释:

    正向:在浏览器中输入url后,用该url去匹配规则(URL_PATTERNS

    反向:根据URL规则,生成一个地址

    首先,在urls的根中,使用namespace

    django4/urls.py

    urlpatterns = [
        url(r'^admin/', include(admin.site.urls)),
        url('booktest/', include('booktest.urls', namespace='booktest'))
    ]

    在子urls中,添加name

    booktest/urls.py

    urlpatterns = [
        url('^$',views.index), # 路由到views.py中的index()函数
        url('^(d+)$',views.show, name="show"),
    ] 

    在模板中使用反向地址解释

    {% url name p1 p2 ... %}

    其中,这里的name是指namspace:name

    <a href="{% url 'booktest:show' 123 %}">跳转</a>

     5、过滤器

    # 语法:
    {{ 变量|过滤器 }}
    # 比如:
    {{ name|lower  }}
    # 表示将变量name的值全部变成小写
    # 竖线|可以理解为python中的圆点(.)
    # 可以在if标签中,使用过滤器,并结合运算符一起使用
    {% if name|length > 2 %}
    
    # 过滤器可以用来串联,构成过滤器链
    name | lower | upper
    
    # 过滤器可以传递参数
    list | join:”,”
    
    # 设置默认值的过滤器
    value | default:”0”
    
    #设置日期
    value | date:”YYYY-mm-dd”

    常用的django过滤器参考:https://www.cnblogs.com/huangxm/p/6286144.html 

     6、模板继承

    很多网站的头部(页头)、底部(页脚)都是一样的。

    把多个页面通用的部分抽取出来,做成父模板。然后在子模板中继承父模板,再实现各自的差异。

    相关的概念:

    block标签。在父模板中预留区域,在子模板中进行填充

    定义父模板base.html

    {% block block_name %}
    这里可以定义默认值。如果不定义默认值,表示默认值为空
    {% endblock block_name %}

    extends继承。写在子模板文件的第一行

    定义子模板index.html

    {% extends ‘base.html’ %}
    {% block block_name %}
    实际填充内容
    {% endblock block_name %}

    如下例子:

    定义父模板

    templates/booktest目录下创建base.html

    templates/booktest/base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>标题</title>
        {% block head %}
        {% endblock head %}
    </head>
    <body>
        <h1>页头:logo</h1>
        <hr/>
        {% block content %}
        <h1>默认的内容</h1>
        {% endblock content %}
        <hr/>
        <h1>页脚:联系我们</h1>
    </body>
    </html>

    子模板

    templates/booktest/index2.html

    {% extends 'booktest/base.html' %}

    路由和视图略写了。

    如果要修改中间的内容:

    可以在index2.html中添加

    {% extends 'booktest/base.html' %}
    {% block content %}
    <h1>修改后的内容</h1>
    {% endblock content %}

     

    7、HTML转义

    通过视图往模板输出带html标签的内容的时候

    booktest/views.py

    def htmlTest(request):
        context = {'text1':'<h2>123</h2>'}
        return render(request, 'booktest/htmlTest.html', context)

    对应的模板捕获

    templates/booktest/htmlTest.html

    <body>
        {{text1}}
    </body>

    其实这里是做了html的转义。当我们给一段html格式的字符串的时候,到了模板中会自动的转义成特殊字符。最终原封不动的输出

    实际上它使用的就是escape过滤器进行自动转义,所以下面两句是一样的效果

    {{text1}}
    {{text1 | escape }}

    当需要按照它指定的格式输出的时候,考虑使用safe过滤器,目的是关闭转义

    {{text1 | safe }}

    如果有一整块代码都需要转义,考虑使用autoescape,并通过设置on打开转义,设置off关闭转义

    {% autoescape off %}
        {{text1}}
    {% endautoescape %}

    如果是在模板代码中直接写html字符串

    {{ text2 | default:'<h2>456</h2>' }}

    则直接输出456,不需要转义

  • 相关阅读:
    c语言练习24——数列求和
    Excel 常用属性的一小部分
    常见问题一之拼接表格 js传递参数变量 Json接收值
    关于下拉列表HtmlDownlistFor的使用
    Quay 基础版安装和部署
    Prometheus使用blackbox_exporter监控端口及网站状态(七)
    在CentOS 8上安装PostgreSQL 13 | RHEL 8
    nfs配置以及No route to host解决
    LNMP分离安装
    Linux配置和管理设备映射多路径multipath
  • 原文地址:https://www.cnblogs.com/kumata/p/9687532.html
Copyright © 2011-2022 走看看