05-Django模板

一、模板概述

  • 模板組成
HTML代碼
動(dòng)態(tài)插入的代碼(挖坑、填坑邏輯控制代碼)
  • 作用
快速生成HTML頁(yè)面
  • 優(yōu)點(diǎn)
模板的設(shè)計(jì)實(shí)現(xiàn)了業(yè)務(wù)邏輯與現(xiàn)實(shí)內(nèi)容的分離
視圖可以使用任何模板
  • 模板處理
加載
渲染

二、定義模板

  • 變量
- 視圖傳遞給模板的數(shù)據(jù)
- 變量遵守標(biāo)識(shí)符規(guī)則
- 語(yǔ)法
  {{ var }}
- 注意
  變量若不存在,則插入空的字符串
- 點(diǎn)語(yǔ)法
 字典查詢、屬性或方法、數(shù)字索引 
  • 標(biāo)簽
- 語(yǔ)法
  {% tag %}
- 作用
  在輸出中創(chuàng)建文本
  控制邏輯和循環(huán)
  • 單行注釋
  {# 注釋內(nèi)容 #}
  • 標(biāo)簽if
- 語(yǔ)法1
  {% if 條件 %}
      語(yǔ)句
  {% endif %}
- 語(yǔ)法2
  {% if 條件 %}
      語(yǔ)句1
  {% else %}
      語(yǔ)句2
  {% endif %}
- 語(yǔ)法3
  {% if 條件 %}
      語(yǔ)句1
  {% elif 條件 %}
      語(yǔ)句2
  {% elif 條件 %}
      語(yǔ)句3
  ....
  {% else %}
      語(yǔ)句
  {% endif %}
- 例如
  {% if username %}
      歡迎 <span> {{username}} </span> 回來(lái)
  {%else%}
      游客登錄,新用戶注冊(cè)有驚喜!
  {%endif%}
  • 標(biāo)簽for
- 格式1
  {% for 變量 in 列表 %}
      語(yǔ)句
  {% endfor %}
- 格式2
  {% for 變量 in 列表 %}
      語(yǔ)句1
  {% empty %}
      語(yǔ)句2
  {% endfor %}
  備注: 列表為空或列表不存在時(shí)執(zhí)行語(yǔ)句2
- 格式3
  {{forloop.counter}} 表示當(dāng)前是第幾次循環(huán)
- 例如
  {% for student in students %}
      <li>
          我叫{{student.sname}},性別{{student.ssex}},今年{{student.sage}}歲,座右銘:"{{student.sbrief}}"。
      </li>
  {% endfor %}
- 例如
  <ul>
      {% for name in names %}
          {% if forloop.counter|divisibleby:2 %}
              <li style="color: red"> {{forloop.counter}} - {{name}} </li>
          {% else %}
              <li style="color: blue"> {{forloop.counter}} - {{name}} </li>
          {% endif %}
      {% empty %}
          <li> 沒(méi)有學(xué)生喔. </li>
      {% endfor %}
  </ul>
  • 標(biāo)簽comment
- 作用
  多行注釋
- 例如
  {% comment %}
      <p>姓名: {{student.sname}}</p>
      <p>性別: {{student.ssex}}</p>
      <p>年齡: {{student.sage}}</p>
      <p>座右銘: {{student.sbrief}} </p>
  {% endcomment %}
  • 標(biāo)簽ifequal、ifnotequal
- 作用
  判斷值1與值2是成立
- 例如
  {% ifequal 'hello' 'world' %}
      <h1> 喔,hello和world一樣呢。 </h2>
  {% endifequal %}
- 例如
  # return render(request, 'meituan/testtemp.html',{'class1':'python03','class2':'python03'})
  {% ifequal class1 class2 %}
      <p>你們?cè)谕粋€(gè)班級(jí)呢。</p>
  {% else %}
      <p>你們是不同班級(jí)。</p>
  {% endifequal %}
  • 過(guò)濾器
- 作用
  在變量被顯示前修改它
- 語(yǔ)法
  {{ var|過(guò)濾器 }}
- lower 小寫(xiě)
  <h1> {{str|lower}} </h1>
- upper 大寫(xiě)
  <h1> {{str|upper}} </h1>
- join 傳遞參數(shù)(參數(shù)用引號(hào)引住)
  <h1> {{list|join:'#'}} </h1>
- default 默認(rèn)值(如果一個(gè)變量沒(méi)有被提供或值為false、空,可以使用默認(rèn)值)
  <h1> {{username|default:'游客'}} </h1>
- date 根據(jù)給定格式轉(zhuǎn)換日期為字符串
  <h1> {{dateValue|date:'y-m-d'}} </h1>
  • 標(biāo)簽inlcude

- 作用
  加載模板并以標(biāo)簽內(nèi)的參數(shù)渲染
- 格式
  {% include '模板目錄' 參數(shù)1 參數(shù)2 %}
- 例如:
  # 不傳遞參數(shù)
  {% include "content.html" %}
  # 傳遞參數(shù)scoreList
  {% include "content.html" with scores=scoreList  %}

由零合一,先完成小細(xì)節(jié),最后使用include一起包含進(jìn)去!

  • 標(biāo)簽url
- 作用
  反向解析
- 格式
  {% url 'namespace:name' p1 p2 %}

備注: 具體看下面詳細(xì)說(shuō)明。

  • 標(biāo)簽block、extends
- 作用
  用于模板的繼承

備注: 具體看下面詳細(xì)說(shuō)明。

  • 標(biāo)簽autoescape
- 作用
  用于HTML轉(zhuǎn)義

備注: 具體看下面詳細(xì)說(shuō)明。

  • 標(biāo)簽csrf_token
- 作用
  用于跨域請(qǐng)求偽造保護(hù)
- 格式
  {% csrf_token %}

備注: 具體看下面詳細(xì)說(shuō)明。

三、反向解析

- 反向解析語(yǔ)法
  {% url 'namespace:name' p1 p2 %}

- 項(xiàng)目的urls.py文件中
  url(r'^meituan/', include('app.urls', namespace='app') )

- 應(yīng)用的urls.py文件中
  # 路由(帶參數(shù))  
  url(r'^goods/(\d+)/$',views.goods, name='goods'),

  # 視圖函數(shù)(帶參數(shù),和url與之對(duì)應(yīng))
  def goods(request, page):
    return HttpResponse('商品列表: 第%s頁(yè)' % page)
  

- 模板(帶有參數(shù)的)
  <a href="{% url 'app:goods' 3 %}"> 商品列表 </a>
  <a href="{% url 'app:students' student.id %}">{{ student.s_name }}</a>

備注:
  name屬性,即是給對(duì)對(duì)應(yīng)的url添加一個(gè)名字;
  但是使用 name 也存在一定的問(wèn)題 ,比如在同一個(gè)項(xiàng)目中的不同的app中 name 可能會(huì)重名;
  Django在反解URL時(shí),會(huì)在項(xiàng)目全局順序搜索,當(dāng)查找到第一個(gè)name指定URL時(shí),立即返回;
  當(dāng)不小心定義相同的name時(shí),可能會(huì)導(dǎo)致URL反解錯(cuò)誤,為了避免這種事情發(fā)生,引入了命名空間;
  namespace命名空間;

反向解析場(chǎng)景: 正常情況下頁(yè)面中設(shè)置的商品頁(yè)鏈接地址都是goods/,而在服務(wù)器中路由如果發(fā)生一些細(xì)微的改變時(shí),那么在頁(yè)面中所有關(guān)于商品頁(yè)鏈接地址都需要修改。為此可以使用反向解析解決此問(wèn)題。

四、模板繼承

  • 作用
模板繼承可以減少頁(yè)面內(nèi)容的重復(fù)定義,實(shí)現(xiàn)頁(yè)面的復(fù)用。
  • block標(biāo)簽
- 作用
  在父木模板中預(yù)留區(qū)域,子模板去填充
- 語(yǔ)法
  {% block 標(biāo)簽名 %}
  {% endblock 標(biāo)簽名 %}  
  • extends標(biāo)簽
- 作用
  繼承模板,需要寫(xiě)在模板文件的第一行
- 語(yǔ)法
  {% extends '父模板路徑' %}
  • 示例(定義父模板)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  {% block title %}
  {% endblock title %}
  <style>
      #header,#footer{
          height: 300px;
          background: red;
          line-height: 300px;
          color: white;
          text-align: center;
          font-size: 30px;
      }
      #footer{
          background: blue;
      }
  </style>
  {% block style %}
  {% endblock style %}
</head>

<body>
  <!--父模板(很多頁(yè)面中,頭部和尾部都是一致的)-->
  <div id="header">header</div>

  <!--主體內(nèi)容不同,需要各部分進(jìn)行填充-->
  <div id="content">
      <!--主體內(nèi)容不確定,就直接這樣寫(xiě)即可-->
      {% block content %}
      {% endblock content %}

      <br>
      <br>
      {% block test %}
      {% endblock test %}
  </div>

  <div id="footer">footer</div>
</body>

</html>
  • 示例(定義子模板1)
{% extends 'meituan/base.html' %}

{% block content %}
  <h1> 首頁(yè) --- 主體內(nèi)容 </h1>
  <a href="{% url 'meituan:about' %}">關(guān)于我們</a>
{% endblock content %}
  • 示例(定義子模板2)
{% extends 'meituan/base.html' %}

{% block title %}
  <title>關(guān)于我們</title>
{% endblock title %}

{% block style %}
<style>
  h2{
      background: black;
      color: white;
  }
</style>
{% endblock style %}

{% block content %}
  <h1> about關(guān)于我們 </h1>
{% endblock content %}

<!--繼承,可以填充,也可以不填充-->
{% block test %}
  <h2>我住隔壁,我姓王,你有事情我?guī)兔Α?lt;/h2>
{% endblock test %}

五、HTML轉(zhuǎn)義

  • 問(wèn)題
<!--views.py-->
return render(request,'meituan/test2.html',{'code': '<h1>今天是周一.</h1>'})

<!--HTML轉(zhuǎn)義-->
{{code}}

<!--問(wèn)題-->
將接受到的code當(dāng)前普通字符串渲染
  • 轉(zhuǎn)義
將接受到字符串當(dāng)成HTML代碼渲染
<!--方式1-->
{{code|safe}}

<!--方式2-->
<!--關(guān)閉自動(dòng)轉(zhuǎn)義-->
{% autoescape off %}
  {{code}}
{% endautoescape %}

六、CSRF

- 跨域請(qǐng)求偽造
    某些惡意網(wǎng)站包含鏈接、表單、按鈕、JS,利用用戶登錄在瀏覽器中認(rèn)證,從而攻擊服務(wù)
- 放置CSRF
    在settings.py文件中MIDDLEWARE添加'django.middleware.csrf.CsrfViewMiddleware'
    在form表單中添加 '{% csrf_token %}'
- 例如
<form action="{% url 'app:login' %}" method="post">
    {% csrf_token %}
    <input type="text" placeholder="輸入驗(yàn)證碼" name="text"> <br>
    <input type="submit" value="驗(yàn)證">
</form>

在沒(méi)有放置CSRF時(shí),會(huì)報(bào)錯(cuò)一下錯(cuò)誤Forbidden (403) CSRF verification failed. Request aborted. More information is available with DEBUG=True.。

七、驗(yàn)證碼

  • 作用
- 在用戶注冊(cè)、登錄頁(yè)面的使用使用,為了防止暴力請(qǐng)求,減輕服務(wù)器的壓力
- 防止CSRF的一種方式

request.session.get["k1"],如果不存在則會(huì)報(bào)錯(cuò),為了防止出錯(cuò)可以>request.session.get('k1',none)

  • 示例(視圖之生成驗(yàn)證碼)
# 驗(yàn)證碼
def verifycode(request):
    # 導(dǎo)入繪圖模塊
    from PIL import Image,ImageDraw,ImageFont
    # 導(dǎo)入隨機(jī)函數(shù)模塊
    import random
    # 文件操作
    import io

    # 定義變量,用于圖片的背景色、寬、高
    # random.randrange()返回指定遞增基數(shù)集合中的一個(gè)隨機(jī)數(shù)
    bgcolor = (random.randrange(20,100),random.randrange(20,100),random.randrange(20,100))
    width = 100
    heigh = 50

    # 創(chuàng)建圖片
    image = Image.new('RGB',(width,heigh),bgcolor)

    # 創(chuàng)建畫(huà)筆對(duì)象
    draw = ImageDraw.Draw(image)

    # 調(diào)用畫(huà)筆的point函數(shù),繪制噪點(diǎn)
    for i in range(0,100):
        xy = (random.randrange(0,width),random.randrange(0,heigh))
        fill = (random.randrange(0,255),255,random.randrange(0,255))
        draw.point(xy,fill=fill)

    # 定義驗(yàn)證碼的備選值
    str = '1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm'

    # 隨機(jī)選取4個(gè)值作為驗(yàn)證碼
    rand_str = ''
    for i in range(0,4):
        rand_str += str[random.randrange(0,len(str))]

    # 構(gòu)建字體對(duì)象
    # font = ImageFont.truetype(path) # 指定路徑加載字體
    # font = ImageFont.load_default() # 加載一個(gè)默認(rèn)的字體
    # truetype(font=None, size=10, index=0, encoding="", layout_engine=None)
    font = ImageFont.truetype('fonts/Songti.ttc',40)
    # font = ImageFont.truetype('fonts/STXINGKA.ttf',40)

    #構(gòu)建字體顏色
    fontcolor1 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor2 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor3 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor4 = (255, random.randrange(0, 255), random.randrange(0, 255))

    # 繪制4個(gè)字
    # def text(self, xy, text, fill=None, font=None, anchor=None, *args, **kwargs):
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor1)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor2)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor3)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor4)

    # 釋放畫(huà)筆
    del draw

    # 存入session,用于驗(yàn)證
    request.session['verify'] = rand_str

    # 文件操作
    buff = io.BytesIO()
    # 將圖片保存在內(nèi)存中,文件類型png
    image.save(buff,'png')

    # 將內(nèi)存中圖片數(shù)據(jù)返回給客戶端,MIME類型為圖片類型
    # 直接是返回驗(yàn)證碼圖片
    return HttpResponse(buff.getvalue(),'image/png')

PIL(Python Imaging Library)是Python一個(gè)強(qiáng)大方便的圖像處理庫(kù),名氣也比較大,不過(guò)只支持到Python 2.7。Pillow是PIL的一個(gè)派生分支,但如今已經(jīng)發(fā)展成為比PIL本身更具活力的圖像處理庫(kù)。目前最新版本是3.0.0。
ython 3.x 安裝Pillow: pip install Pillow

  • 示例(視圖之登錄)
# 登錄操作
def verifycodefile(request):
    # 獲取到session的flag標(biāo)志值
    flag = request.session.get("flag", True)
    str = ''
    if flag == False:
        str = "請(qǐng)重新輸入"

    # 清空session
    request.session.clear()

    return render(request, 'meituan/verifycodefile.html', {"flag": str})
  • 示例(視圖之登錄驗(yàn)證碼驗(yàn)證)
# 登錄驗(yàn)證
def verifycodecheck(request):
    # 輸入的驗(yàn)證碼
    # upper()轉(zhuǎn)為大寫(xiě)
    code1 = request.POST.get('verifycode').upper()
    # session驗(yàn)證碼
    code2 = request.session['verify'].upper()
    
    if code1 == code2:  # 驗(yàn)證成功
        return render(request,'meituan/success.html')
    else:   # 重新登錄操作
        request.session["flag"] = False
        return redirect('/meituan/verifycodefile/')
  • 示例(url管理器)
urlpatterns=[
    url(r'^verifycode/$',views.verifycode), # 驗(yàn)證碼測(cè)試
    url(r'^verifycodecheck/$',views.verifycodecheck),    # 驗(yàn)證操作
    url(r'^verifycodefile/$',views.verifycodefile),  # 帶驗(yàn)證碼登錄
]
  • 示例(模板)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄 | 驗(yàn)證碼測(cè)試</title>
</head>
<body>
    <!--驗(yàn)證碼-->
    <!--默認(rèn)什么都添加,就是直接顯示-->


    <!--添加登錄功能驗(yàn)證-->
    <form action="/meituan/verifycodecheck/" method="post">
        {%csrf_token%}
        <input type="text" name="verifycode" />
        <img src="/meituan/verifycode/" /> <br>
        <input type="submit" value="驗(yàn)證" /> <br>
        <span>{{flag}}</span>
    </form>

</body>
</html>

作者:西門奄
鏈接:http://www.itdecent.cn/u/77035eb804c3
來(lái)源:簡(jiǎn)書(shū)
簡(jiǎn)書(shū)著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、模板概述 模板組成HTML代碼動(dòng)態(tài)插入的代碼(挖坑、填坑邏輯控制代碼) 作用快速生成HTML頁(yè)面 優(yōu)點(diǎn)模板的設(shè)...
    EndEvent閱讀 1,631評(píng)論 0 3
  • 模塊間聯(lián)系越多,其耦合性越強(qiáng),同時(shí)表明其獨(dú)立性越差( 降低耦合性,可以提高其獨(dú)立性)。軟件設(shè)計(jì)中通常用耦合度和內(nèi)聚...
    riverstation閱讀 2,222評(píng)論 0 8
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • 在上一個(gè)章節(jié),我們已經(jīng)創(chuàng)建了一個(gè)基礎(chǔ)的Blog程序?,F(xiàn)在我們將使用一些Dajngo高級(jí)功能,去實(shí)現(xiàn)一個(gè)完整的blo...
    金金剛狼閱讀 3,758評(píng)論 1 12
  • 切換到創(chuàng)建項(xiàng)目的目錄 cd C:\Users\admin\Desktop\DjangoProject創(chuàng)建名為pr...
    在努力中閱讀 3,539評(píng)論 2 3

友情鏈接更多精彩內(nèi)容