Python—Django中的模板(template)

作者:BerenCamlost

1 定義模板

1.1 變量

  • 視圖傳遞給模板的數據
  • 要遵守標識符規則
  • 語法 {{var}}(var代表變量)
  • 【注意】:如果使用的變量不存在,則插入的是空字符串
  • 在模板中使用點語法,點後邊的東西按如下順序進行匹配
    • 字典查詢
    • 屬性或者方法
    • 數字索引

在模板中調用方法

  1. sunck/models.py:
# 插入到Students類中的方法
def get_name(self):
    return self.sname
  1. sunck/views.py:
# templates 測試
def templates(request):
    stu = Students.stuObj2.get(sname='劉德華')
    return render(request, 'sunck/templates測試/templates1.html', {'stu': stu})
  1. sunck/urls.py:
    path('template/', views.templates),
  1. sunck/templates測試/templates.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板測試</title>
</head>
<body>
<h1>{{ stu.get_name }}</h1>
<h1>{{ stu.sname }}</h1>

</body>
</html>
  1. 效果:
    劉德華
  • 【注意】:在模板中調用方法時不能傳遞參數

1.2 標籤

1.2.1 語法

{% tag %}

1.2.2 作用

  1. 在輸出中創建文本
  2. 控制邏輯和循環

1.2.3 if

  1. 格式:
<!--if語句-->
{% if 表達式 %}
    語句
{% endif %}

<!--else語句-->
{% if 表達式 %}
    語句1
{% else %}
    語句2
{% endif %}

<!--else if語句-->
{% if 表達式1 %}
    語句1
{% elif 表達式2 %}
    語句2
    ·
    ·
    ·
{% elif 表達式n %}
    語句n
{% else %}<!--可有可無-->
    語句e
{% endif %}
  1. 舉例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板測試</title>
</head>
<body>
    <h1>{{ stu.get_name }}</h1>
    <h1>{{ stu.sname }}</h1>

    <h1>num={{ num }}</h1>
    {% if num is 10 %}
    <h2>You are a handsome boy</h2>
    {% elif num is 20 %}
        <h2>you are a Very handsome boy</h2>
    {% else %}
        <h2>You are not a handsome boy</h2>
    {% endif %}
</body>
</html>

在Views.py中給num傳一個數字,得到效果如下圖所示:
2

1.2.4 for

{% for 變量 in 列表 %}
{#語句1#}
{% empty %}
{#語句2#}
{% endfor %}
  • 【注意】:當列表爲空或者不存在時,執行empty語句,empty可有可無
  • {{ forloop.counter }}表示循環次數,可以用在for語句中,例如:
    <ul>
        {% for student in stu1 %}
        {#語句1#}
            <li>{{ forloop.counter }}:{{ student.sname }}---{{ student.scontend }}</li>
        {% empty %}
        {#語句2#}
            <li>沒有學生信息</li>
        {% endfor %}
    </ul>
  • views.py文件中爲:
def templates(request):
    stu1 = Students.stuObj2.all()
    # stu1 = Students.stuObj2.filter(sname__startswith="劉")
    # stu1 = Students.stuObj2.filter(sname__startswith="Liu")
    return render(request, 'sunck/templates測試/templates1.html', { 'stu1': stu1})

1.2.5 comment

  • 格式
{% commnet %}
    被註釋的內容
{% endcomment %}
  • 作用:相當於多行註釋,被註釋的內容不再執行

1.2.6 ifequal/ifnotequal

  • 【作用】:判斷是否相等或者不相等
  • 【格式】:
{% ifequal 值1 值2 %}
    語句1
{% endifequal %}  # 如果值1等於值2,執行語句1,否則不執行語句1

1.2.7 include

  • 【作用】:加載模板並以標籤內的參數渲染
  • 【格式】:{% include '模板目錄' 參數1 參數2 %}

1.2.8 url

  • 【作用】:反射解析
  • 【格式】:{% url 'namespace: name' p1 p2 %}

1.2.9 csrf_token

  • 【作用】:用於跨站請求僞造保護
  • 【格式】:{% csrf_token %}

1.2.10 block, extends

  • 【作用】:用於模板的繼承

1.2.11 autoescape

  • 【作用】:用於HTML轉義

1.3 過濾器

  • 【語法】:{{var|過濾器}}
  • 【作用】:在變量被顯示前修改它,只是加一個效果,對變量不會造成影響

1.3.1 upper/lower

  • 大寫和小寫,示例:
{#5. 過濾器#}
<h1>原型:{{ str }}</h1>
<h1>upper:{{ str|upper }}</h1>
<h1>lower:{{ str|lower}}</h1>
  • 【效果】:
    效果

1.3.2 過濾器可以傳遞參數

  • 下面以var|join:'str'爲例解釋傳參的過程:
# templates 測試
def templates(request):
    stu1 = Students.stuObj2.all()
    return render(request, 'sunck/templates測試/templates1.html', {'stu1': stu1,})
<h2>{{ stu1|join:"--的兒子是-->" }}</h2>

【效果】(涉及隱私我打了馬賽克):
效果

1.3.3 default默認值

  • 如果一個變量沒有被提供,或者值爲false,空,我們可以通過 default 語法使用默認值
  • 【示例】:<h2>{{ stu1.sname|default:'啥都麼的' }}</h2>

1.3.4 date

  • 【作用】:根據給定格式轉換日期爲字符串
  • 【示例】:{{dateVal|date:'y-m-d'}}
    以年月日的形式顯示日期,dateVal是一個日期變量

1.3.5 escape

  • 【作用】:HTML轉義

1.3.6 加減乘除

  • 【示例】:
<ul>
    <li>num:{{ num }}</li>
    <li>num+10:{{ num|add:10 }}</li>
    <li>num-5:{{ num|add:-5 }}</li>
    <!--num/1*5-->
    <li>num*5:{% widthratio num 1 5 %}</li>
    <li>num/2:{% widthratio num 2 1 %}</li>
</ul>
  • 效果:
    效果

1.3.7 給之前的學生列表加背景顏色

  • |divisibleby:2:可被2整除
<ul>
    {% for student in stu1 %}
        {% if forloop.counter|divisibleby:2 %}
            <li style="background-color: gray">{{ forloop.counter }}:{{ student.sname }}---{{ student.scontend }}</li>
        {% else %}
            <li style="color: orange">{{ forloop.counter }}:{{ student.sname }}---{{ student.scontend }}</li>
        {% endif %}
    {% empty %}
        <li>沒有學生信息</li>
    {% endfor %}
</ul>
  • 【效果】(打碼真的費時間):
    效果

1.4 註釋

  • 【單行註釋】:{{# #}}
  • 【多行註釋】:{%comment%}....{%endcomment%}

2 反向解析

2.1 作用

即使url變動,也可以根據namespace和name反向解析出正確的域名,從而實現超鏈接的正確執行。

2.2 示例

<a href="{% url 'sunck:good' %}">反解析連接good</a>
# project/project/urls.py
urlpatterns = [
    path('sunck/', include('sunck.urls', namespace="sunck")),
]
# project/sunck/urls.py
urlpatterns = [
    path('template/good/', views.good, name='good'),
]

2.3 傳入參數

模板:

<a href="{% url 'sunck:good' 1 %}">反解析連接good</a>

url:

path('template/good/<int:id>', views.good, name='good'),

views視圖:

# templates-反向解析 測試
def good(request, id):
    return render(request, 'sunck/templates測試/good.html', {'num': id})

good模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>good</title>
</head>
<body>
    <h1>good--{{ num }}</h1>
</body>
</html>

3 模板繼承

3.1 作用

  • 模板繼承可以減少頁面的重複定義,實現頁面的重用

3.2 block標籤

  • 【作用】:在父模板中預留區域 ,子模板去填充
  • 【語法】:
{% block 標籤名 %}
...
{% endblock 標籤名 %}

3.3 extends標籤

  • 繼承模板,需要寫在模板文件的第一行
  • 【語法】:
{% extends 'myApp/base.html(父模板路徑)' %}
{% block 標籤名 %}
內容
{% endblock 標籤名 %}

3.4 示例

  • base.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>base</title>
</head>
<body>
    <div id="header">
        <h1>header</h1>
    </div>
    <div id="main">
        {% block main %}

        {% endblock main %}
    </div>
    <div id="footer">
        <h1>footer</h1>
    </div>

</body>
</html>
  • main.html:
{% extends "sunck/模板繼承/base.html" %}
{% block main%}
    <h1>{{ 'main'|upper }}</h1>
{% endblock main %}

4 HTML轉義

4.1 問題

# templates 測試
def templates(request):
    return render(request, 'sunck/templates測試/templates1.html',
                  {
                   'str2': '<h1>HTML轉義</h1>'
                   })
{#6 HTML轉義#}
{{ str2 }}
  • 這時的輸出爲<h1>HTML轉義</h1>,未經過渲染,而我們想要的輸出是

    HTML轉義

4.2 解決

  • 過濾器safe可以關閉轉義,escape開啓轉義
  • 標籤{% autoescape off %}...{% endautoescape %}關閉自動轉義,將off變成on開啓自動轉義

4.3 示例

  • html文件:
{#6 HTML轉義#}
{{ str2 }}
{{ str2|escape }}
{{ str2|safe }}
{% autoescape on %}
    1{{ str2 }}
    2{{ str2 }}
{% endautoescape %}
{% autoescape off %}
    1{{ str2 }}
    2{{ str2 }}
    3{{ str2 }}
{% endautoescape %}
  • 【效果】:
    效果

5 CSRF

5.1 跨站請求僞造

某些惡意網站包含鏈接,表單,按鈕,js,利用登錄用戶在瀏覽器中認證,從而攻擊服務

5.2 防止CSRF

  1. 在settings.py文件的MIDDLEWARE增加'django.middleware.csrf.CsrfViewMiddleware'
    在這裏插入圖片描述
  2. 上述方法會將所有的跨站請求屏蔽,爲了允許自身的跨站請求服務,應該在HTML頁面中加入{% csrf_token %},如:
<form action="../register/" method="post">
    {% csrf_token %}
    <!--這裏的action需要和後面的urls路徑相對應-->
    姓名:<input type="text" name="name" value=""/>
    <hr>
    性別:<input type="radio" name="gender" value="1"><input type="radio" name="gender" value="0"><hr>
    年齡:<input type="text" name="age" value=""/>
    <hr>
    愛好:<input type="checkbox" name="hobby" value="power"/>權利<input type="checkbox" name="hobby" value="money">金錢<input type="checkbox" name="hobby" value="beauty">美女<input type="checkbox" name="hobby" value="Tesla">Tesla
    <hr>
    <input type="submit" value="註冊">
</form>

6 驗證碼

6.1 作用

  • 在用戶註冊,登錄頁面的時候使用,爲了防止暴力請求,減輕服務器的壓力
  • 是防止CSRF的一種方式

6.2 源碼及效果

6.3 輸入驗證碼

6.3.1 視圖

def verifi_code(request):
    return render(request, 'sunck/templates測試/verificationcode.html', )


# 展示結果
def show(request):
    code = request.POST.get('code')
    right_code = request.session['verification_code']
    if code.upper() == right_code.upper():
        return HttpResponse('對了!'+right_code)
    else:
        return HttpResponse('錯了!'+code+'----'+right_code)

6.3.2 url

    path('VerificationCode/code', VerificationCode.verification_code),
    path('VerificationCode/', VerificationCode.verifi_code),
    path('VerificationCode/show', VerificationCode.show, name='show'),

6.3.3 模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>驗證碼</title>
</head>
<body>
    <h3>請輸入驗證碼</h3>
    <form method="post" action="{% url 'sunck:show' %}">
        {% csrf_token %}
        <input type="text" name="code" value=""/>
        <img src="/sunck/VerificationCode/code">
        <hr>
        <input type="submit" value="登錄"/>
    </form>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章