1. 程式人生 > 其它 >mycat設定讀寫分離

mycat設定讀寫分離

django模板

配置

在settings.py中配置,BACKEND表示要使用那種模板引擎;DIRS表示template的目錄(可以是多個);APP_DIRS表示是否使用app中的template目錄(即形如這樣的app/templates/);OPTIONSDjangoTemplates的一些引數,預設即可。
比如:


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

要是想使用Jinja2:把BACKEND改為django.template.backends.jinja2.Jinja2即可。
當使用多個模板引擎時,django會按照列表的順序找到html檔案,然後渲染。需要注意的是:django查詢到任何一個匹配的模板後便停止搜尋,所以這是個類似url搜尋的短路操作!

使用

一般來說我們可以使用django.shortcuts.render指定template檔案,然後進行渲染:

from django.shortcuts import render

def index
(request):
return render(request, "app01/index.html")

render背後其實是這樣的:

from django.template import loader
from django.http import HttpResponse


def render(request, template_name, context=None, content_type=None, status=None, using=None):
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)

render的引數

  • request是一個HttpRequest物件
  • template_name:一般來說一個HTML檔案,其路徑需要在settings中配置好
  • context:需要傳一個字典,裡面的鍵值對可以在html頁面中供模板引擎使用
  • content_type:內容型別

模板語言

django作為一個重型web框架,自然少不了模板語言。這主要是用於動態渲染HTML頁面的。

變數

使用兩個大括號獲取,對於物件的屬性等資料可以在其基礎上是用.獲取。對於Model物件,可以通過.來取值,也可以使用.xxx_set的方式進行反向查詢,但查詢操作不太適合在模板中完成。
比如:

# views.py
from django.shortcuts import render


def index(request):
    data = {
        "username": "lczmx",
        "age": 22,
    }

    msg_list = ["1234", "abcd", "6666"]
    print(request.session.get(""))
    return render(request, "app01/index.html", {"data": data, "msg_list": msg_list})
<!-- app01/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app01 index</title>
</head>
<body>
<p>{{ data.username }}</p>
<p>{{ data.age }}</p>

<p>{{ msg_list.0 }}</p>
</body>
</html>

標籤

django模板引擎的標籤就相當於python的程式碼塊,以{% %}的定義。
django已經為我們貼心地內建了一下標籤 :

標籤作用
autoescape 自動轉義開關
block 塊引用
comment 註釋
csrf_token CSRF令牌
cycle 迴圈物件的值
debug 除錯模式
extends 繼承模版
filter 過濾功能
firstof 輸出第一個不為False的引數
for 迴圈物件
for … empty 帶empty說明的迴圈
if 條件判斷
ifchanged 如果有變化,則..
include 匯入子模版的內容
load 載入標籤和過濾器
lorem 生成無用的廢話
now 當前時間
regroup 根據物件重組集合
resetcycle 重置迴圈
spaceless 去除空白
templatetag 轉義模版標籤符號
url 獲取url字串
verbatim 禁用模版引擎
widthratio 寬度比例
with 上下文變數管理器

對於使用方法,見:https://docs.djangoproject.com/zh-hans/3.2/ref/templates/builtins/

as語法的使用
使用as語法可以將返回值賦值給一個變數,如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app01 index</title>
</head>
<body>
{% url "app01:index" as index_url %}
<a href="{{ index_url }}">index page</a>
</body>
</html>

模板繼承
extends與block結合,可以讓你的一些模板繼承其他模板,從而極大地減少程式碼的複用程度。
模板繼承允許你建立一個基本的“骨架”模板,它包含了你網站的所有常用元素,並定義了子模板可以覆蓋的 塊。

我們先看一個例子,看看模板繼承:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css">
    <title>{% block title %}My amazing site{% 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 骨架文件,你可以用它來製作一個兩欄式頁面。“子”模板的工作是用內容填充空塊。

在這個例子中,block 標籤定義了三個塊,子模板可以填入其中。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 標籤,然後用子模板的內容替換這些塊。根據 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>

請注意,由於子模板沒有定義 sidebar 塊,所以使用父模板的值來代替。父模板中 {% block %} 標籤中的內容總是被用作後備。
你可以根據需要使用任意層次的繼承。一種常見的使用繼承的方式是像以下的三層繼承:

  1. 建立一個 base.html 模板,以保持你網站的主要外觀和風格。
  2. 為你網站的每個“部分”建立一個 base_SECTIONNAME.html 模板。
    例如,base_news.html、base_sports.html。這些模板都是對 base.html 的擴充套件,幷包括特定部分的樣式/設計。
  3. 為每種型別的頁面建立單獨的模板
    如新聞文章或部落格條目。這些模板擴充套件了相應的部分模板。

下面是一些關於繼承工作的技巧:

  1. 如果你在模板中使用 {% extends %},它必須是該模板中的第一個模板標籤。否則,模板繼承將無法使用。
  2. 基礎模板中的 {% block %} 標籤越多越好。記住,子模板不需要定義所有的父塊,所以你可以在一些塊中填入合理的預設值,然後只定義以後需要的塊。鉤子多比鉤子少好。
  3. 如果你發現自己的內容在多個模板中重複,可能意味著你應該把這些內容移到父模板中的 {% block %}。
  4. 如果你需要從父模板中獲取塊的內容,{{ block.super }} 變數就可以做到這一點。如果你想新增到父模板的內容中,而不是完全覆蓋它,這很有用。使用 {{ block.super }} 插入的資料不會被自動轉義,因為如果需要的話,它已經在父模板中被轉義了。
  5. 通過使用與繼承模板相同的模板名稱,{% extends %} 可以在覆蓋模板的同時繼承它。結合 {{ block.super }},這可以成為一種強大的小規模定製方式。 比如官方給出的這個例子:擴充套件複寫模板

{% block %} 之外使用模板標籤 as 語法建立的變數不能在塊中使用。例如,這個模板不會呈現任何東西:

{% translate "Title" as title %}{% block content %}{{ title }}{% endblock %}

為了增加可讀性,你可以給你的 {% endblock %} 標籤 起一個 名字。例如:

{% block content %}
...
{% endblock content %
}

在較大的模板中,這種技術可以幫助你看到哪些{% block %} 標籤正在被關閉。
最後,請注意,你不能在同一個模板中定義多個同名的 block 標籤

過濾器

過濾器就相當於python語法中的函式,其使用語法是:{{ 變數 | 過濾器:引數 }},其中,對於沒有引數的過濾器來說,:引數這部分省略。

內建過濾器

過濾器 說明
add 加法
addslashes 新增斜槓
capfirst 首字母大寫
center 文字居中
cut 切除字元
date 日期格式化
default 設定預設值
default_if_none 為None設定預設值
dictsort 字典排序
dictsortreversed 字典反向排序
divisibleby 整除判斷
escape 轉義
escapejs 轉義js程式碼
filesizeformat 檔案尺寸人性化顯示
first 第一個元素
floatformat 浮點數格式化
force_escape 強制立刻轉義
get_digit 獲取數字
iriencode 轉換IRI
join 字元列表連結
json_script 生成script標籤,帶json資料
last 最後一個
length 長度
length_is 長度等於
linebreaks 行轉換
linebreaksbr 行轉換
linenumbers 行號
ljust 左對齊
lower 小寫
make_list 分割成字元列表
phone2numeric 電話號碼
pluralize 複數形式
pprint 除錯
random 隨機獲取
rjust 右對齊
safe 安全確認
safeseq 列表安全確認
slice 切片
slugify 轉換成ASCII
stringformat 字串格式化
striptags 去除HTML中的標籤
time 時間格式化
timesince 從何時開始
timeuntil 到何時多久
title 所有單詞首字母大寫
truncatechars 截斷字元
truncatechars_html 截斷字元
truncatewords 截斷單詞
truncatewords_html 截斷單詞
unordered_list 無序列表
upper 大寫
urlencode 轉義url
urlize url轉成可點選的連結
urlizetrunc urlize的截斷方式
wordcount 單詞計數
wordwrap 單詞包裹
yesno 將True,False和None,對映成字串‘yes’,‘no’,‘maybe’

一般的使用例子,以add為例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app01 index</title>
</head>
<body>
<p>你明年的年齡是{{ data.age | add:1 }}</p>
</body>
</html>

其他的內建過濾的參考

關於safe字串,見:幾種safe字串的方法

自定義標籤及過濾器

一般來說,預設的標籤和過濾器已經夠我們應付簡單場景的了,面對複雜的需求的話,我們可以使用自定義標籤和過濾器的辦法。

自定義標籤及過濾器的位置就是 Django 應用內。如果它們關聯至某個已存在的應用,在那裡將它們打包就很有用;否則,它們能被新增至新應用。當一個 Django 應用被新增至 INSTALLED_APPS,所以其在常規位置定義的標籤都可以在模板中自動載入。
自定義標籤

  1. app中建立一個名為templatetags的Python 包
  2. 在templatetags下建立一個py檔案,用於放標籤函式
  3. 建立一個函式
  4. 使用django.template.Library物件的simple_tag方法裝飾,可以指定name引數,表示標籤名,空的時候為函式名
  5. 重啟django
  6. 在template中使用load標籤將自定義標籤引入
  7. {% xx %}的形式使用

例子:

# 第1和第2步省略
# app的目錄機構(部分):
# app01
# ├── admin.py
# ├── apps.py
# ├── templatetags
# │      ├── __init__.py
# │      ├── mytags.py
# │      └── __pycache__
# │          ├── __init__.cpython-38.pyc
# │          └── mytags.cpython-38.pyc
# ├── tests.py
# ├── urls.py
# └── views.py
# app01/templatetags/mytags.py

from django import template


# 第4步
register = template.Library()


# 指定name引數為t1,在template中就只能用t1了
@register.simple_tag(name="t1")
def my_tag(x, y, *args):
    print(x, y)
    print(args)
    return "t1"
	
{# 使用load自定義標籤,mytags是py檔案,t1是name指定的引數, 若不指定,則為函式名#}{% load t1 from mytags %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app01 index</title>
</head>
<body>
{# 使用t1標籤 #}{% t1 12 234 134 %}
</body>
</html>

自定義過濾器

  1. app中建立一個名為templatetags的Python 包
  2. 在templatetags下建立一個py檔案,用於放過濾器函式
  3. 建立一個函式
  4. 使用django.template.Library物件的filter方法裝飾,可以指定name引數,表示過濾器名,空的時候為函式名
  5. 重啟django
  6. 在template中使用load標籤將自定義過濾器引入
  7. {{ xx | yy:z}}的形式使用

filter和tag很像,就裝飾器、函式引數、模板使用方法有所區別,例子:

# app01/templatetags/myfilter.py

from django import template

register = template.Library()


@register.filter(name="f1")
def my_filter(x, y, z):
    print(x, y, z)
    return "f1"

{# 使用load自定義過濾器,myfilter是py檔案 #}{% load f1 from myfilter %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app01 index</title>
</head>
<body>
{# 使用f1過濾器 #}{{ "hello"|f1:123 }}
</body>
</html>

load標籤的使用
load是用於載入一個自定義模板標籤集。

上面在例子使用了load標籤,下面記錄一下其語法。
在使用時可以把load類比成python的import
比如現在在templatetags下有兩個檔案,每個檔案中有一個標籤或過濾器函式:

# app/templatetags/myfilter.py

from django import template

register = template.Library()


@register.filter(name="f1")
def my_filter(x, y):
    print(x, y)
    return "f1"

# ########################################################## #

# app/templatetags/myfilter.py

from django import template

register = template.Library()


@register.simple_tag(name="t1")
def my_tag(x, y, *args):
    print(x, y)
    print(args)
    return "t1"

那麼就有兩種方法載入:
第一種

{# load的是py檔案#}{% load  mytags %}{% load myfilter %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app01 index</title>
</head>
<body>
{# 直接使用 #}{% t1 12 234 134 %}{{ "hello"|f1:123 }}
</body>
</html>

方法二:
此方法可以同時載入多個,以空格隔開,如:{% load f1 f2 from myfliter %}

{#{% load t1 from mytags %}#}{#{% load f1 from myfilter %}#}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app01 index</title>
</head>
<body>
{# 使用 #}{% t1 12 234 134 %}{{ "hello"|f1:123 }}
</body>
</html>

我的github
我的部落格
我的筆記