1. 程式人生 > 其它 >2022.5.16 django模板語法、匯入、繼承及ORM關鍵字

2022.5.16 django模板語法、匯入、繼承及ORM關鍵字

2022.5.16 django模板語法、匯入、繼承及ORM關鍵字

  • 模板語法之過濾器(類似於內建函式)
  • 模板語法之標籤(類似於流程控制)
  • 自定義過濾器、標籤、inclusion_tag
  • 模板的匯入
  • 模板的繼承
  • ORM測試環境搭建
  • ORM關鍵字使用

一、模板語法之過濾器(類似於內建函式)

1、語法結構

{{ 資料物件|過濾器名稱:引數 }}  過濾器最多隻能額外傳輸一個引數

eg: <p>統計資料的長度:{{ s1|length }}</p>

2、常見過濾器

django模板語法提供了60+過濾器,我們先了解部分;

1.
<p>統計資料的長度:{{ s1|length }}</p>
2.
<p>算術加法或者字串加法:{{ n1|add:111 }}、{{ s1|add:'big baby' }}</p>
3.
<p>將數字轉成合適的檔案計量單位:{{ file_size|filesizeformat }}、{{ file_size1|filesizeformat }}</p>
4.
<p>判斷當前資料物件對應的布林值是否是False:{{ b|default:'前面的值對應的布林值是False' }}、{{ s1|default:'前面的值對應的布林值是False' }}</p>
5.
<p>時間格式化:{{ ctime|date:'Y-m-d' }}</p>
6.
<p>索引切片:{{ s1|slice:'0:8' }}</p>
7.
<p>按照空格擷取指定個數的文字:{{ s2|truncatewords:5 }}、{{ s1|truncatewords:1 }}</p>
8.
<p>按照字元個數擷取文字(包含三個點):{{ s2|truncatechars:5 }}、{{ s1|truncatechars:10 }}</p>
9.
<p>移除指定的字元:{{ info|cut:'|' }}</p>
10.
<p>是否取消轉換:{{ tag1 }}、{{ tag1|safe }}、{{ scripts1|safe }}、{{ res }}</p>

ps:最後一個|safe啟發了我們以後用django開發全棧專案前端頁面程式碼(主要指HTML程式碼)也可以在後端編寫

二、模板語法之標籤(類似於流程控制)

ps:在django模板語法中寫標籤的時候,只需要寫關鍵字然後tab鍵就會自動補全;

1、語法結構

{% 名字 ...%}
{% end名字 %}

2、if判斷與for迴圈

<!-- if判斷 -->
{% if b %}
    <p>你好啊</p>
{% elif s1 %}
    <p>他好呀</p>
{% else %}
    <p>大家好</p>
{% endif %}

<!-- for迴圈 -->
{% for i in l1 %}
<p>{{i}}</p>
{% endfor %}

    提供了forloop關鍵字,可以在for迴圈前提下使用,forloop結果如下:
    結果x,{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}  <!-- 這是forloop的一條記錄 -->
    	counter0:從零開始計算索引,當前元素的索引值
	counter:從1開始計算索引,當前元素的索引值
	revcounter:從1開始計算索引,將索引值反過來後當前元素的索引值
	revcounter0:從0開始計算索引,將索引值反過來後當前元素的索引值
	first:表示當前元素是否是第一個元素
	last:表示當前元素是否是最後一個元素
    ...
    <!-- for迴圈中forloop使用+if判斷 -->
    {% for i in l1 %}
    {% if forloop.first %}
	    <p>這是第一次迴圈</p>
    {% elif forloop.last %}
	    <p>這是最後一次迴圈</p>
    {% else %}
	    <p>中間迴圈</p>
    {% endif %}
    {% empty %}  <!-- for迴圈物件為空時執行下面程式碼 -->
	    <p>for迴圈物件為空 自動執行</p>
    {% endfor %}

ps:針對字典同樣提供了keys、values、items方法
    {% for foo in user_info %}
    	{{ foo }}  <!-- 預設取字典k值 -->
    {% endfor %}

    {% for foo in user_info.keys %}
    	{{ foo }}  <!-- 取字典所有k值 -->
    {% endfor %}

    {% for foo in user_info.values %}
    	{{ foo }}  <!-- 取字典所有v值 -->
    {% endfor %}

    {% for foo in user_info.items %}
    	{{ foo }}  <!-- 取字典所有鍵值對,元組形式 -->
    {% endfor %}

三、自定義過濾器、標籤、inclusion_tag

"""
1.在應用下需要建立一個名為templatetags的資料夾
2.在該資料夾內建立一個任意名稱的py檔案
3.在該py檔案內需要先提前編寫兩行固定的程式碼
	from django import template
	register = template.Library()
"""

from django import template
register = template.Library()

# 1.自定義過濾器:只能接收兩個引數(filter)
@register.filter(is_safe=True)
def index(a, b):
    return a + b
    # 前端:
    {% load mytag %}
    {{ n1|index:666 }}
    
# 自定義簡單標籤:可以接收任意的引數(simple_tag)
@register.simple_tag(name='my_tag')  # 括號裡為自定義名稱
def func1(a, b, c, d):
    return a + b + c + d
	# 前端:
	{% my_tag 1 2 3 4 %}  # 引數之間空格隔開即可
    
# 自定義inclusion_tag
@register.inclusion_tag('left.html')  # 括號裡寫對應前端頁面
def func2(n):
    l1 = []
    for i in range(1, n + 1):
        l1.append(f'第{i}頁')
    return locals()
{% func2 10 %}
    ###left.html###
    <ul>
        {% for foo in l1 %}
            <li>{{ foo }}</li>
        {% endfor %}
    </ul>
'''自定義inclusion_tag標籤,相當於是對區域性的html進行資料梳理等操作,然後返回頁面指定呼叫的位置以供展示使用'''

四、模板的匯入(瞭解)

{% include 'xxx.html' %}
# 可以將一個html檔案作為另一個html檔案的區域性展示出來,一般匯入的html檔案中只需寫對應的標籤即可
好處:可以多次使用在不同的頁面

html註釋與django模板語法註釋

<!-- -->     # 是HTML的註釋語法
{# #}        # 是django模板語法的註釋
"""
區別:
HTML的註釋可以在前端瀏覽器頁面上直接檢視到;
模板語法的註釋只能在後端檢視,前端瀏覽器檢視不了;
"""

五、模板的繼承

類似於面向物件的繼承,繼承了某個頁面就可以使用該頁面上的所有內容;

應用場景:一般有很多網站的很多頁面,都差不多,只是區域性有變化,就是使用了模板的繼承;

繼承方式:

# 1.先在模板中通過block劃定將來可以被修改的區域
    {% block content %}
    ...
    {% endblock %}
    
# 2.子板繼承模板
	{% extends 'home.html' %}
    
# 3.修改模板劃定的區域(和劃定方式一樣)
    {% block content %}  # 修改內容
    ...
    {% endblock %}
    
    {% block css %}  # 修改CSS樣式
    <style>...</style>
    {% endblock %}
    
    {% block content %}  # 修改js
    <script>...</script>
    {% endblock %}
    
# 4.子頁面還可以重複使用父頁面的內容
	{{ block.super }}

六、ORM測試環境搭建

在django框架中,如果我們不想使用網路請求的方式使用ORM操作資料庫,就需要有專門的測試環境:

# 在test.py檔案中
import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
    import django
    django.setup()
    
    from app01 import models  # 就可以操作指定應用中的資料庫了
    ...

其實pycharm也給我們提供了一個簡單的方式使用ORM操作資料庫,即python console視窗,可以直接使用ORM操作

python console
...

七、ORM關鍵字使用

1、資料庫遷移及反向遷移命令

django自帶的sqlite3資料庫,功能很少,並且針對日期型別不精確;
# 在terminal視窗中操作
1.資料庫正向遷移命令(將類操作對映到表中)
	python3 manage.py makemigrations
  	python3 manage.py migrate
2.資料庫反向遷移命令(將表對映成類)
	python3 manage.py inspectdb
	# 該方法可以在原資料庫中先使用,就會自動建立該資料庫下所有的類,然後重新配置settings檔案中的資料庫,建立新的資料庫,然後執行上面1的遷移操作,就可以將原資料庫中的表複製到新資料庫中了

2、ORM關鍵字操作

資料準備:

# models.User.objects.create(name='jason',age=18)
# models.User.objects.create(name='tony',age=28)
# models.User.objects.create(name='kevin',age=28)
# models.User.objects.create(name='kerry',age=38)
# models.User.objects.create(name='jack',age=38)
# models.User.objects.create(name='tom',age=28)
# models.User.objects.create(name='oscar',age=18)

ORM操作:

(1)filter() 篩選條件
res = models.User.objects.all()  # 查詢所有的資料
	結果QuerySet可以看成是列表套物件
    
res = models.User.objects.filter()  # 括號內填寫篩選條件,不寫相當於all()    
	結果QuerySet可以看成是列表套物件
    
res = models.User.objects.filter(pk=1)  # 想通過主鍵篩選資料,可以直接寫pk,會自動定位到當前表的主鍵欄位,無需你自己檢視具體欄位名稱

es = models.User.objects.filter(pk=1)[0]  # 直接獲取資料物件,結果中第一個物件
res = models.User.objects.filter(pk=1).first()  # 獲取結果集中第一個物件
res = models.User.objects.filter().last()  # 獲取結果集中最後一個物件
	QuerySet支援索引取值,但是django不推薦使用,因為索引不存在會直接報錯,推薦使用first(),last()
    
res = models.User.objects.filter(pk=1, name='kevin').first()  # 括號內支援填寫多個篩選條件,預設是and關係

res = models.User.objects.filter().filter().filter().filter().filter()  # 只要是QuerySet物件就可以繼續點物件方法(類似於jQuery鏈式操作)
(2)values() 取值
res = models.User.objects.all().values('name','age')  # QuerySet,可以看成是列表套字典
res = models.User.objects.values('name','age')  # QuerySet,可以看成是列表套字典,指定欄位,all不寫也表示從所有資料中操作
res = models.User.objects.filter(pk=2).values('name')  # 可以看成是對結果集進行欄位的篩選
res = models.User.objects.all().values_list('name', 'age')  # QuerySet,可以看成是列表套元組
(3)distinct() 去重
res = models.User.objects.all().distinct()  # 資料物件中如果包含主鍵,不可能去重
res = models.User.objects.values('name').distinct()  # 可以先獲取具體資料,然後去重
(4)order_by() 排序
res = models.User.objects.order_by('age')  # 預設是升序
res = models.User.objects.order_by('-age')  # 該為降序
res = models.User.objects.order_by('age', 'pk')  # 也支援多個欄位依次排序
(5)exclude() 取反操作
res = models.User.objects.exclude(name='jason')  # 取反操作
(6)reverse() 顛倒順序
res = models.User.objects.reverse()  # 不起作用
res1 = models.User.objects.order_by('age').reverse()  # 只有在order_by排序之後才可以
(7)count() 計數
res = models.User.objects.count()  # 統計結果集的個數
(8)exist() 判斷是否存在
res = models.User.objects.exists()
res = models.User.objects.filter(name='jasonNB').exists()  # 判斷結果集中是否有資料,有返回True,沒有返回False
(9)get() 獲取資料物件
res = models.User.objects.get(pk=1)  # 直接獲取資料物件,但是不推薦使用,因為不存在就報錯
res = models.User.objects.get(pk=100)  # 條件不存在,直接報錯
res = models.User.objects.filter(pk=100)  # 條件不存在,返回空,推薦使用filter篩選,作用一樣