Djangoのテンプレートシステム

文法

レンダリングするテンプレートについて、あなたは2つのだけ特殊記号(構文)を覚えておく必要があります

{{}}と{%}%

{{}}、{%%に関連するロジック}に関連付けられた変数。

変数

{{名前}}変数:で使用Djangoテンプレート言語の構文をクリックします。

  テンプレートエンジンが変数に遭遇すると、変数を計算し、その結果自分自身でそれを置き換えます。名前付き変数は任意の英数字とアンダースコア(「_」)の組み合わせが含まれます。変数名にはスペースや句読点を含めることはできません。

  デプス問い合わせ牙城記号(。)テンプレート言語で特別な意味を持っています。テンプレートシステムはドット(「」)に遭遇すると、それはこの順序の問い合わせになります。

   辞書引き(辞書引き)
   プロパティやメソッドクエリ(属性やメソッドのルックアップ)
   デジタルインデックスクエリ(数値索引参照)

注意事項:

  1. 計算結果の値が呼び出された場合は、パラメータなしで呼び出されます。呼び出しの結果は、テンプレートの値になります。
  2. 変数が存在しない場合、システムはデフォルトの設定で値string_if_invalidテンプレートオプションを、挿入します「」(空文字列)です。

view.pyコード

def index(request):
    import datetime
    s = "hello"
    l = [111, 222, 333]  # 列表
    dic = {"name": "yuan", "age": 18}  # 字典
    date = datetime.date(1993, 5, 2)  # 日期对象

    class Person(object):
        def __init__(self, name):
            self.name = name
        def dream(self):
            return 'dreamer'
    person_yuan = Person("chao")  # 自定义类对象
    person_egon = Person("yantao")
    person_alex = Person("jinxin")

    person_list = [person_yuan, person_egon, person_alex]

    return render(request, "index.html", {"l": l, "dic": dic, "date": date, "person_list": person_list})
    # return render(request,'index.html',locals())
    #locals()获取函数内容所有的变量,然后通过render方法给了index.html文件进行模板渲染,如果你图省事,你可以用它,但是很多多余的变量也被传进去了,效率低

テンプレートのサポート言葉遣い

<h4>{{s}}</h4>
<h4>列表:{{ l.0 }}</h4>
<h4>列表:{{ l.2 }}</h4>
<h4>字典:{{ dic.name }}</h4>
<h4>日期:{{ date.year }}</h4>

<!--取列表的第1个对象的name属性的值-->
<h4>类对象列表:{{ person_list.0.name }}</h4>
<!--取列表的第1个对象的dream方法的返回值,如果没有返回值,拿到的是none-->
<h4>类对象列表:{{ person_list.0.dream }}</h4>
注意:
    调用对象里面的方法的时候,不需要写括号来执行,并且只能执行不需要传参数的方法,如果你的这个方法需要传参数,那么模板语言不支持,不能帮你渲染

フィルタ

変数の表示を変更するには、フィルタを使用して、Djangoテンプレート言語では。

  フィルタの構文:{{値| FILTER_NAME:パラメータ}}

  フィルタを適用|「」パイプ記号を使用してください。

  例えば:{{名前|低い}}次に、変数名は、下部フィルタを適用した後、その値が表示されます。ここでアクションで下はすべて小文字のテキストです。

  注意事項:

  1. フィルターは「チェーン」の動作をサポートしています。即ち、別のフィルタへの入力としてフィルタ出力。
  2. フィルタは、例えば、パラメータを受け入れることができる:{{SSS | truncatewords:30}}、SSSの最初の30ワードが表示されます。
  3. Filterパラメータには、それは引用符で囲む必要があり、スペースが含まれています。{|:「」}参加{リスト:}このようなカンマ、そのようなものとして、リストの要素を接続するために使用される空間として
  4. 「|」の周りにスペースはスペースを入れずにスペースなしではありません
    length  -- 获取数据长度,没参数 
    返回值的长度,作用于字符串和列表
    {{ value|length }}
    
    default -- 设置默认值
    如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值。
    {{ value|default:"nothing"}}
    
    filesizeformat -- 将数字转换成可读的表示
    将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)
    {{ value|filesizeformat }}
  
  slice -- 切片
  切片,如果 value="hello world",还有其他可切片的数据类型
  {{value|slice:"2:-1"}}
  
    date -- 时间格式化
  格式化,如果 value=datetime.datetime.now()
  {{ value|date:"Y-m-d H:i:s"}}
  
  safe -- 让标签字符串识别成标签 (脚本攻击--xss)
  很多网站,都会对你提交的内容进行过滤,一些敏感词汇、特殊字符、标签、黄赌毒词汇等等,你一提交内容,人家就会检测你提交的内容,如果包含这些词汇,就不让你提交,其实这也是解决xss攻击的根本途径
  {{ value|safe}}
  
  truncateChars -- 截断字符
  如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。    参数:截断的字符数
  {{ value|truncatechars:9}} #注意:最后那三个省略号也是9个字符里面的,也就是这个9截断出来的是6个字符+3个省略号。
  
  truncateWords -- 截断单词
  在一定数量的字后截断字符串,是截多少个单词。
    例如:‘hello girl hi baby yue ma’,
    {{ value|truncatewords:3}}  #上面例子得到的结果是 'hello girl h1...'
      
    cut -- 移除元素
    移除value中所有的与给出的变量相同的字符串
    {{ value|cut:' ' }}
    
    join -- 拼接
    使用字符串连接列表,就像Python的str.join(list)
    {{ list|join:', ' }}

タグタグ

タグは次のようになります{% tag %}タグが変数よりも複雑である:いくつかの追加情報が出力テキスト、番号で作成または論理ループを通る流れを制御するために、いくつかの変数は、テンプレートの後にロードするために使用されるであろう。いくつかのタグは開始タグと終了タグを必要とする(例えば、{% tag %} ...タグのコンテンツ... {%のENDTAGの%})。

ラベルの

各要素を:のために書き、その後、自動的にサイクルのタブキー構造を生成し、サイクルは非常に基本的な、とても簡単な使用で、何の休憩など、複雑な機能はありません、あなたはJSを渡す必要があります

リスト内の移動

{% for person in person_list %}
    <p>{{ person.name }}</p>  <!--凡是变量都要用两个大括号括起来-->
{% endfor %}

あなたは使用することができます{% for obj in list reversed %}完了するために、逆サイクルを。

辞書を横断:

{% for key,value in d1.items %} 
    {{ forloop.counter }}
      <li>{{ key }} -- {{ value }}</li>
{% endfor %}

ループのための他の方法

forloop.counter            当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0           当前循环的索引值(从0开始)
forloop.revcounter         当前循环的倒序索引值(从1开始)
forloop.revcounter0        当前循环的倒序索引值(从0开始)
forloop.first              当前循环是不是第一次循环(布尔值)
forloop.last               当前循环是不是最后一次循环(布尔值)
forloop.parentloop         本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等

他の方法の例

示例
    {#  {% for key,value in d1.items %}#}
    {#    {{ forloop.counter }}#}
    {#      <li>{{ key }} -- {{ value }}</li>#}
    {#  {% endfor %}#}

    {#    {% for key,value in d1.items %}#}
    {#    {{ forloop.counter0 }}#}
    {#      <li>{{ key }} -- {{ value }}</li>#}
    {#  {% endfor %}#}

    {#    {% for key,value in d1.items %}#}
    {#      {{ forloop.revcounter }}#}
    {#        <li>{{ key }} -- {{ value }}</li>#}
    {#    {% endfor %}#}

    {#      {% for key,value in d1.items %}#}
    {#        {{ forloop.revcounter0 }}#}
    {#          <li>{{ key }} -- {{ value }}</li>#}
    {#      {% endfor %}#}

    {#      {% for key,value in d1.items %}#}
    {#        {{ forloop.first }}#}
    {#          <li>{{ key }} -- {{ value }}</li>#}
    {#      {% endfor %}#}


    <!-- forloop.parentloop示例 -->
    {#<ul>#}
    {#    {% for dd2 in d2 %}#}
    {#      <li>#}
    {#        {% for ddd2 in dd2 %}#}
    {#          {{ forloop.parentloop.counter }}#}
    {#          {{ forloop.counter }}#}
    {#          <a href="">{{ ddd2 }}</a>#}
    {#        {% endfor %}#}
    {##}
    {#      </li>#}
    {#  {% endfor %}#}
    {#</ul>#}

    <!-- empty示例 -->
    {#<ul>#}
    {#   {% for foo in d3 %}#}
    {#       <li>{{ foo }}</li>#}
    {#   {% empty %}#}
    {#     <li>查询的内容啥也没有</li>#}
    {#  {% endfor %}#}
    {##}
    {#</ul>#}

以下のために...空

forオプション付きラベル{% empty %}空にするか、見つからないために述べ句は、操作があってもよいです。

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

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

ラベルの場合

{% if %}変数の評価を持って、その値が「真」である場合には(存在している、空ではなく、ない偽のブール値の型)、ブロック意志の出力に対応するコンテンツ。

{% if num > 100 or num < 0 %}
    <p>无效</p>  <!--不满足条件,不会生成这个标签-->
{% elif num > 80 and num < 100 %}
    <p>优秀</p>
{% else %}  <!--也是在if标签结构里面的-->
    <p>凑活吧</p>
{% endif %}

場合にのみ、他があるかもしれません

{% if user_list|length > 5 %}  <!--结合过滤器来使用-->
  七座豪华SUV
{% else %}
    黄包车
{% endif %}

文は、サポートした場合、または==、>、<,! =、<=、> =、、で、ではありませんで、で、判断両側のスペース上の条件に注意を払うことはありません。

ラベル付き

等号の前後にスペースを追加しないでください

{% with total=business.employees.count %}
    {{ total }} <!--只能在with语句体内用-->
{% endwith %}
        或
{% with business.employees.count as total %}
    {{ total }}
{% endwith %}

csrf_tokenラベル

私たちは道を投稿するフォームを送信すると、文句を言う私たちはCSRF内部のミドルウェアの構成設定内で償却するためにああを防御機構であることを覚えているだろう、それ自体は償却すべきではありませんが、それを使用する方法を学ばなければならない、とそうでありませんその動作がforbidenされていることを確認するために、この事を介して取得することができます。
    このラベルはに置き換えられたテンプレートのレンダリング時に内部のフォームページの形で、{%csrf_token%}を書き込むための任意の位置にこの事を(どのフォームでフォームに注意)を、クロスサイトリクエストフォージェリの保護に使用されている隠された、このラベルを値はランダムな文字列、提出されたときに、このことはまた、提出された、最初のものは、ページを追加するために私たちのバックエンドレンダリング時間であるあなたは、私はあなたにフォームを与えるフォームを介してデータを送信すると、それから、あなたが取ります我々はまた、この事の背景を保持ジャンゴ、そしてあなたが対応する検証を行うことができ、同じ値の値が、私はあなたにトークンを与えるこの店ではありませんので、これの内容は、私が、私はあなたを禁止し、ないと、あなたを知っていました学ぶ私はあなたに、通常のページの送信フォームデータを与えるとして、あなたのユーザーが投稿していない場合、我々は後に、あなたは最初に、戻ってこれまでちょうど私達の1のように、あなたがどうなるパスをユーザーに知っているか、いない何をすべきかの値私は、このランディングページリクエストに行きますが、要求は、その後、私は、要求が違法であることを伝えることができ、アナログに直接データを送信します アンチ爬虫類や私のウェブサイト上の悪意のある攻撃、ミドルウェアの後に私たちはこの事で手の込んだが、今はそれが起こったのか理解する必要があり、Djangoは防衛のこのセットを追加します理由を理解しています。

ポスト要求クローラーの簡単なシミュレーションを送信:

import requests

res = requests.post('http://127.0.0.1:8000/login/',data={
    'username':'chao',
    'password':'123'
})

print(res.text)

注記

{# ... #}

注意事項

1. Django的模板语言不支持连续判断,即不支持以下写法:
{% if a > b > c %}
...
{% endif %}
2. Django的模板语言中属性的优先级大于方法(了解)
def xx(request):
    d = {"a": 1, "b": 2, "c": 3, "items": "100"}
    return render(request, "xx.html", {"data": d})

テンプレートの継承

Djangoのテンプレートエンジンは継承されているテンプレートの最も強力で最も複雑な部分です。テンプレートの継承は、あなたのサイトのすべての要素が含まれている基本的な「スケルトン」テンプレートを作成することができます、そしてあなたはキルトのブロックをカバーすることができますテンプレートを定義することができます。

テンプレートの継承を理解しやすいです

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{%/span> endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

 このテンプレートは、我々はそれを呼び出すbase.html、それは簡単なHTMLスケルトンが2ページレイアウトで使用することができます定義されています。その内容と「サブテンプレート」の仕事は、空のブロックを埋めます。

 この例では、blockタグは、3つのコンテンツで満たされたキルトテンプレートブロックを定義することができます。blockテンプレートエンジンに教える:子テンプレートは、これらの場所にテンプレートを無効にすることができます。

 子テンプレートは次のようになります。

{% extends "base.html" %}
 
{% block title %}My amazing blog{% endblock %}
 
{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

extendsタグは、ここで重要です。これは、このテンプレートが別のテンプレートを「継承」テンプレートエンジンに指示します。システムはステンシルテンプレートを処理すると、まず、それは親テンプレートを探します - この場合には、「base.html」です。

那时,模版引擎将注意到 `base.html` 中的三个 `block` 标签,并用子模版中的内容来替换这些block。根据 `blog_entries` 的值,输出可能看起来是这样的:
<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>My amazing blog</title>
</head>
 
<body>
    <div id="sidebar">
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
    </div>
 
    <div id="content">
        <h2>Entry one</h2>
        <p>This is my first entry.</p>
 
        <h2>Entry two</h2>
        <p>This is my second entry.</p>
    </div>
</body>
</html>

読みやすくするため、また、あなたの与えることができます{% endblock %}タグの名前を

{% extends "base.html" %}

钩子:{% block title %}
        xxx
    {% endblock %}
钩子:{% block title %}
        xxx
    {% endblock title %}
    
钩子:{% block title %}
        {{ block.super }}  #显示模板内容
        xxx
    {% endblock title %}

 大規模なテンプレートでは、この方法は、あなたがはっきりとものを見るのを助けるする  {% block %}ラベルが閉じられています。

同じ名前の複数のテンプレートで定義することができないblockタグ。

パッケージ

ページのコンテンツが別のファイルに格納され、ナビゲーション、フッター情報成分として、使用され、その後、必要な場合に使用されてもよく、次の構文により、ファイル内のどこにでも導入することができます。

{% include 'navbar.html' %}

例:以下のナビゲーションバーはnav.html、あります 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .c1{
            background-color: red;
            height: 40px;
        }
    </style>
</head>
<body>

<div class="c1">
    <div>
        <a href="">xx</a>
        <a href="">dd</a>
    </div>
</div>

</body>
</html>

ページの組み込みナビゲーションバー、test.htmlという

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% include 'nav.html' %}
<h1>xxxxxxxxxx</h1>
</body>
</html>

コンポーネントとプラグインとの間の差

组件是提供某一完整功能的模块,如:编辑器组件,QQ空间提供的关注组件 等。

而插件更倾向封闭某一功能方法的函数。

这两者的区别在 Javascript 里区别很小,组件这个名词用得不多,一般统称插件。

カスタムタグやフィルタ

1、アプリで現在の設定ではINSTALLED_APPSは、simple_tagカスタムを見つけることができないそうジャンゴ。

2. (のみtemplatetags可能なモジュールの名前)におけるAPP templatetagsでモジュールを作成

3、などの任意の.pyファイルを、作成します。my_tags.pyを

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

@register.simple_tag  #和自定义filter类似,只不过接收更灵活的参数,没有个数限制。
def simple_tag_multi(v1,v2):
    return  v1 * v2

@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

htmlファイルからのインポートを使用する前にmy_tags.pyで作成したsimple_tagとフィルタを定義します

{% load my_tags %} 

(呼び出す方法)simple_tagとフィルタを使用します

-------------------------------.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 %}

注意:フィルタは、他の文のために、後の場合で使用することができ、ないsimple_tag

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

日(57)

自定义过滤器

1. app应用文件夹中创建一个templatetags文件件,必须是这个名字
2. templatetags文件夹中创建一个 xx.py文件,文件名字随便起

3. 创建自定义过滤器
    from django import template

    register = template.Library()  #register固定的名字,注册器

    # @register.filter
    # def oo(v1,v2):  #不带参数的过滤器
    #     s = v1 + 'xxoo'

    #     return s

    @register.filter
    def oo(v1,v2):  #带参数的过滤器
        s = v1 + v2
        return s
    
4. 使用  html文件中  {% load 文件名 %} 
     {% load xx %}
    {{ values|oo }} -- 无参数
    {{ values|oo:'asdf' }} -- 有参数

5. 注意:参数最多两个


自定义标签
1. app应用文件夹中创建一个templatetags文件件,必须是这个名字
2. templatetags文件夹中创建一个 xx.py文件,文件名字随便起
3. 创建自定义标签
    @register.simple_tag
    def mytag(v1,v2,v3):  
        s = v1 + '和B哥' + v2 + v3
        return s

4.使用
    {% load xx %}
    {% mytag s1 '和相玺' '和大壮' %}  
5. #可以传多个参数

inclusion_tag

戻すためのマルチHTMLコードセグメント

1. app应用文件夹中创建一个templatetags文件件,必须是这个名字
2. templatetags文件夹中创建一个 xx.py文件,文件名字随便起
3. 创建自定义inclusion_tag
    @register.inclusion_tag('inclusiontag.html')
    def func(v1):
            return {'oo':v1}

4. func的return数据,传给了inclusiontag.html,作为模板渲染的数据,将inclusiontag.html渲染好之后,作为一个组件,生成到调用这个func的地方
5. 使用
    {% load xx %}
    {% func l1 %}

templatetags / my_inclusion.py

from django import template

register = template.Library()


@register.inclusion_tag('result.html')  #将result.html里面的内容用下面函数的返回值渲染,然后作为一个组件一样,加载到使用这个函数的html文件里面
def show_results(n): #参数可以传多个进来
    n = 1 if n < 1 else int(n)
    data = ["第{}项".format(i) for i in range(1, n+1)]
    return {"data": data}#这里可以穿多个值,和render的感觉是一样的{'data1':data1,'data2':data2....}

テンプレート/スニペット/ result.html

<ul>
  {% for choice in data %}
    <li>{{ choice }}</li>
  {% endfor %}
</ul>

テンプレート/ index.htmlを

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>inclusion_tag test</title>
</head>
<body>

{% load inclusion_tag_test %}

{% show_results 10 %}  
</body>
</html>

静的関連ファイル

 JS、CSS、IMGなどの静的ファイルと呼ばれ、その後、ジャンゴ静的ファイルの構成は、我々は、この上のコンテンツを書くには、設定ファイルの設定を記述する必要があります。

1 在项目中创建一个文件夹,比如叫jingtaiwenjian

# STATIC_URL = '/xxx/' #别名,随便写名字,但是如果你改名字,别忘了前面页面里面如果你是通过/xxx/bootstrap.css的时候,如果这里的别名你改成了/static/的话,你前端页面的路径要改成/static/bootstrap.css。所以我们都是用下面的load static的方式来使用静态文件路径
2 STATIC_URL = '/static/' #别名

3 STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'jingtaiwenjian'), #注意别忘了写逗号,第二个参数就是项目中你存放静态文件的文件夹名称
]

ディレクトリ:エイリアスは他の人があなたの静的フォルダの名前を知ることができない、または他の誰かがこのフォルダのパスを通して攻撃することができるようになりますように、あなたが見ることができ試運転段階を経由して、ブラウザ上の安全機構は、エイリアス名です。

  IMG

フロントページの導入は、別名も変更できるので、静的ファイルを書き込んだので、別名マッピングの方法により、静的なファイルパスを取得するために、静的エイリアス負荷を通るパスを見つけるために時間を使います

IMG

{%静的%}

{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />

  JSファイルを参照するときに使用します。

{% load static %}
<script src="{% static "mytest.js" %}"></script>

   ファイル内で使用された多くは、変数として保存することができます

{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>

{%get_static_prefix%}

{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

    若しくは

{% load static %}
{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

おすすめ

転載: www.cnblogs.com/shuai-jie/p/11228328.html