Django框架的基本使用,若依框架
Django框架的基本使用
Django是一個功能強大的web框架
框架模式
1、MVC和MTV框架
MVC:Web服務器開發領域里著名的MVC模式,所謂MVC就是把Web應用分為模型(M),控制器(C)和視圖(V)三層,結構說明如下:
M: models 數據庫相關操作
V: views 視圖,也就是業務邏輯相關操作
C: controller 控制器,也就是通過路徑找到對應視圖函數
MTV:Django的MTV模式本質上和MVC是一樣的,也是為了各組件間保持松耦合關系,只是定義上有些許不同。
M: models 數據庫相關操作
T: templates html文件相關操作(模板渲染等)
V: views 視圖,也就是業務邏輯相關操作
加上一個url控制器,也就是通過路徑找到對應視圖函數
2、WSGI
WSGI(Web Server Gateway Interface)就是一種規范,它定義了web應用程序與web服務器程序之間的接口格式,實現web應用程序與web服務器程序間的解耦。
開發的項目分為兩個部分的程序
1 服務器程序 socket相關功能的模塊,wsgiref、uwsgi等等,負責接收網絡請求并解析網絡請求相關數據,分裝加工成一些可用的數據格式,格式大家都是統一的,方便應用程序的開發
2 應用程序 就是使用接收到的網絡請求相關數據,進行邏輯代碼的開發,比如數據庫相關操作,數據結構的調整、文件操作等等。。。
一、Django的基本使用
1、下載的三種方式:
直接在pycharm中的setting中進行下載
在cmd中通過命令下載:pip install django==版本
在pycharm的Terminal控制臺中進行下載(下載時要注意路徑問題)
2、創建項目
(1)通過cmd或pycharm控制臺的命令創建項目
?先切換到要創建項目的目錄下,然后執行創建項目命令:
django-admin startproject mysite # mysite是項目名稱
?創建項目后會生成如下的目錄,當前目錄下會生成mysite的工程,里面有個主目錄和我們創建的項目目錄同名,在項目目錄下有個manage.py文件,在主目錄下有settings.py\urls.py\wsgi.py,每個文件的功能介紹如下:
manage.py ----- Django項目里面的工具,通過它可以調用django shell和數據庫,啟動關閉項目與項目交互等,不管你將框架分了幾個文件,必然有一個啟動文件,其實他們本身就是一個文件。
settings.py ---- 包含了項目的默認設置,包括數據庫信息,調試標志以及其他一些工作的變量。
urls.py ----- 負責把URL模式映射到應用程序。
wsgi.py ---- runserver命令就使用wsgiref模塊做簡單的web server,后面會看到renserver命令,所有與socket相關的內容都在這個文件里面了,目前不需要關注它。
?一個django項目中可以有多個應用,每個應用完成項目的部分功能,這些功能相對于其他功能來說是相對獨立的,但又同時存在于同一個項目中,每個應用的邏輯數據庫等也都是相對獨立的,每個應用都有屬于自己的模塊單位;開發的時候,都是通過應用來寫邏輯
(2)通過pycharm創建django項目
點擊File --》New Project 選擇第二項 Django
在Location中選擇選項目創建的地址和項目名
Project Interpreter:
Project Interpreter中的Newenvironment using是創建項目執行的虛擬環境
Project Interpreter中的Existing interpreter是使用本地的環境,也可以使用已創建好的虛擬環境
More Settings
Template language:模板引擎;默認是Django的Template模板引擎
如若下載jinja2模板引擎可進行切換,或者其他模板引擎
注:django中的模板引擎未單獨封裝成模塊;jinja2是模仿的的django的Template
Templates folder:存放html文件的文件夾名
Application name:是創建的應用的應用名
create創建完成后執行即可,通過控制臺顯示的鏈接即可訪問
3、運行項目
啟動項目命令:
python manage.py runserver 127.0.0.1:8080
ip和port可以不用寫,不寫時默認是 127.0.0.1:8000
運行成功后,會看到一個項目鏈接,在瀏覽器中輸入此鏈接即可訪問到創建的項目
4、創建應用Application
(1)cmd或pycharm控制器Terminal中創建應用
?要在項目目錄下執行命令進行創建應用
python manage.py startapp 應用名
經常用到的三個文件
models.py 數據庫相關內容
views.py 視圖,業務邏輯代碼相關內容
tests.py 用來寫一些測試代碼,用來測試我們自己寫的視圖的,目前用不到
(2)pycharm中手動創建應用
創建應用文件夾(鼠標右鍵使用python package創建)
在settings.py中找到INSTALLED_APPS在其下面添加應用的配置信息
應用名.apps.應用名Config(后面的應用名的首字母大寫)
5、django項目的導入
請看博客:https://www.cnblogs.com/wylshkjj/p/11983596.html
6、windows中安裝不同版本的python解釋器
在python3.7及以上版本中,使用django框架的時候,django的版本要在2.0或以上,否則會出現問題;python3.6使用django的1.0版本。
當想即使用python3.7和python3.6針對django的不同版本進行創建項目時,python解釋器的安裝要注意,
解釋器安裝請參考博客:https://www.cnblogs.com/wylshkjj/p/13122349.html
二、url路由系統
在django中,url中的路徑寫法是正則,正則里面有無名分組正則,有有名分組正則,那么對應django中的功能,我們稱之為無名分組路由和有名分組路由
在django的1.0版本中路由配置文件urls.py中使用的是url(),里面可以直接使用正則匹配路徑的方式
而在django的2.0版本中路由配置文件urls.py中使用的是path(),里面不能直接使用正則匹配路徑,如需使用正則路徑進行匹配就要使用re_path(),使用前要先導入
1、無命名分組路由
看寫法,urls.py文件中內容如下
urlpatterns = [
...
url(r'^books/(\d+)/(\d+)/', views.book),
#正則里面()分組正則,會將分組中的正則匹配到的內容作為返回值返回
]
簡單分析,偽代碼
'''
當用戶請求的路徑是它: /books/2019/8/
url(r'^books/(\d+)/(\d+)/', views.book), 里面做的事情如下
re.match(^books/(\d+)/,/books/2019/)
2019 和 8 作為位置參數交給了要執行的book視圖函數
視圖函數book的寫法
def book(request,xx,oo):
xx = 2019
oo = 8
pass
'''
視圖views.py文件中函數的寫法
#位置傳參,url中正則^books/(\d+)/(\d+)/,那么第一個()分組匹配到的數據,作為book函數的第二個參數,第二個()分組匹配到的數據,作為book的第三個參數
def book(request, year, month):
print('year', year, 'month', month) #year 2020
# return HttpResponse('%s所有書籍' % year)
return HttpResponse('%s年%s月所有書籍' % (year, month))
使用url路由系統時需要注意幾個點
1. urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則不再繼續。
2. 若要從URL中捕獲一個值,只需要在它周圍放置一對圓括號(正則分組匹配)。
3. 不需要添加一個前導的反斜杠(也就是寫在正則最前面的那個/),因為每個URL 都有。例如,應該是^articles 而不是 ^/articles。
4. 每個正則表達式前面的'r' 是可選的但是建議加上。
5. ^articles$ 以什么結尾,以什么開頭,嚴格限制路徑
2、有名分組路由
其實就玩得正則的有名分組,看示例
Urls.py文件中的寫法
urlpatterns = [
url(r'^admin/', admin.site.urls),
# /books/2020/6/
url(r'^books/(?P\d+)/(?P\d+)/', views.book),
# {'year':2020,'month':6},url類將有名分組正則匹配出來的數據,交給了book視圖函數作為關鍵字參數來使用]
View.py文件中函數的寫法如下
# ^books/(?P\d+)/(?P\d+)/
#獲取到url中的有名分組正則匹配到的數據,那么函數形參名稱必須和有名分組正則的那個名稱相同才可以,也就是按照上面的url來看的話,函數的形參必須是year和month這兩個名稱,并且關鍵字傳參不需要考慮函數形參的位置
def book(request, month, year):
# print('year', year, 'month', month) #year 2020
print(request.path) #/books/2020/6/
# return HttpResponse('%s所有書籍' % year)
return HttpResponse('%s年%s月所有書籍' % (year, month))
3、路徑中的尾部斜杠問題
當用戶通過瀏覽器訪問django框架完整的項目中的某個路徑時,如果用戶在輸入網址路徑的最后,沒有加上/斜杠,比如http://127.0.0.1:8000/test,那么django會發將用戶輸入的網址路徑加上一個后置的/,也就會將路徑變成這樣http://127.0.0.1:8000/test/,然后給瀏覽器發送一個重定向的響應操作,狀態碼為301,那么瀏覽器拿到這個重定向操作之后,就會自動發起一個這樣的路徑請求http://127.0.0.1:8000/test/,所以當我們打開瀏覽器控制臺的network功能查看請求過程時,會看到兩個請求,一個沒有后置的斜杠的,一個是有后置斜杠的。第二個請求才會走到我們的urs.py文件中的路徑配合和分發對應視圖的地方。
我們可以通過一個配置項,告訴django,不要自動加路徑后面的斜杠了,但是需要注意的就是你自己寫的url中的正則,也別加后面的斜杠,不然正則匹配不到。
配置項直接寫在settings配置文件中,任意位置
APPEND_SLASH = False #False表示告訴Django,不加路徑后面的斜杠,默認值是True
5、視圖函數中指定默認值
views.py文件:
# 在路由沒有匹配任何參數的時候,num使用自己的默認值
# 當路由中有分組匹配數據的動作,比如url(r'^test/(\d+)/', views.test),用戶輸入網址:http://127.0.0.1:8000/test/22/,那么22就被匹配到了,會作為參數傳給我們的test函數,那么num的值就變成了22
def test(request, num=10):
print('number>>>',num)
return HttpResponse('test')
urls.py文件
# url(r'^test/', views.test),
url(r'^test/(\d+)/', views.test),
三、Django的視圖
1、request的對象
常用的屬性和方法
print(request) # wsgirequest對象
print(request.path) # 請求路徑 #/index/
print(request.method) # 請求方法
print(request.POST) # post請求提交的數據
print(request.GET) # 獲取url中的查詢參數 #不是針對get請求的
print(request.body) #獲取http請求消息格式的請求數據部分的內容 b''
print(request.META) #請求頭信息
print(request.get_full_path()) # 獲取完整路徑(包含查詢參數的) /index/?a=1&b=3
print(request.FILES) # 上傳的文件對象數據
print(request.FILES.get('file')) # 上傳的文件名
#
print(request.POST.get('username')) # 前端中傳輸的username的值
print(request.POST.get('sex')) # 前端中單選傳輸的sex值
# 多選提交來的數據通過getlist來獲取
print(request.POST.getlist('hobby')) # ['2', '3']
2、response的響應
(1)常用方法
from django.shortcuts import render, HttpResponse, redirect
return HttpResponse('你好') #回復字符串
return render(request,'home.html') #回復html頁面
#重定向方法,參數是個路徑
return redirect('/home/') #封裝了302狀態碼,以及瀏覽器要重定向的路徑
(2)添加響應頭鍵值對
ret = render(request,'home.html')
ret['a'] = 'b' #添加響應頭鍵值對
return ret
(3)添加響應狀態碼
ret = render(request,'home.html', status=202) #render修改狀態碼還可以這樣改
#ret['a'] = 'b' #添加響應頭鍵值對
ret.status_code = 201 #添加響應狀態碼
return ret #回復html頁面
3、CBV和FBV
兩種視圖邏輯的寫法方法
FBV:全稱function based view,就是基于函數來寫視圖邏輯
CBV:全稱class based view,就是基于類來寫視圖
基于類的視圖CBV寫法,如下,views.py文件
from django.views import View
#登錄需求
class LoginView(View):
# get請求 獲取login頁面
def get(self,request):
return render(request,'login.html')
# post請求,獲取post請求提交的數據,并校驗等等
def post(self,request):
print(request.POST)
#
return render(request,'login.html')
url路徑的寫法:urls.py文件
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
url(r'^home/', views.home),
# 類視圖的url寫法
url(r'^login/', views.LoginView.as_view()),
]
4、cbv源碼重點(反射)
from django.views import View
View里面的dispatch方法中的反射邏輯,實現了不同的請求方法,找到我們視圖類中的對應方法執行
5、FBV和CBV加裝飾器
FBV和普通函數加裝飾器方式一樣
示例:
#裝飾器函數
def outer(f):
def inner(request, *args ,**kwargs):
print('前面')
ret = f(request, *args ,**kwargs)
print('后面')
return ret
return inner
#使用裝飾器
@outer
def books(request):
print('FBV執行了')
return HttpResponse('book.html--ok')
CBV加裝飾器
#裝飾器函數
def outer(f):
def inner(request, *args ,**kwargs):
print('前面')
ret = f(request, *args ,**kwargs)
print('后面')
return ret
return inner
#使用裝飾器
#1 引入django提供的裝飾器方法method_decorator來配合裝飾器函數的使用
from django.utils.decorators import method_decorator
@method_decorator(outer,name='get') #CBV加裝飾器方式3
class BookView(View):
#給類方法統一加裝飾器,借助dispatch方法(父類的dispatch方法,就是通過反射來完成不同的請求方法找到并執行我們自己定義的視圖類的對應方法)
# 重寫dispatch方法,dispatch方法是在其他請求方法對應的類方法執行之前執行的
# @method_decorator(outer) #加裝飾器方式2
def dispatch(self, request, *args, **kwargs):
# print('xxxxxx')
ret = super().dispatch(request, *args, **kwargs)
# print('oooooo')
return ret
#CBV加裝飾器的方式1,給單獨的方法加裝飾器
# @method_decorator(outer)
def get(self, request, xx):
print('CBV的get方法')
return render(request, 'book.html')
# @method_decorator(outer)
def post(self,request, xx):
print('CBV的post方法')
return HttpResponse('ok')
四、Django的Template模板
1、Template的基本使用
(1)通過{{ 變量 }}:獲取單個變量值
(2)通過{% 邏輯 %}:獲取邏輯渲染結果
2、變量的使用
Number數據類型,容器數據類型和對象都可以直接進行渲染
(1)返回前端頁面的數據格式
在return返回的時候可以直接寫入參數,區別在于html中渲染的時候直接通過元素直接獲取(使用原參數沒有作用),容器數據類型才有效,number類型無效
return render(request, "index.html", info)
在return返回的時候也可以使用字典的方式,使用字典時,就是直接通過字典的鍵來進行相應的操作
return render(request, "index.html", {'info': info})
(2)句點號的使用:
?在字典數據類型中需要使用句點號和索引搭配才能獲取到相應的值
?同理對象的方法和屬性的調用也是通過句點號,而且要注意調用方法不能加()
# views.py
from django.shortcuts import render
import datetime
# Create your views here.
class obj():
pass
def index(request):
pdd = '1234'
info = {
'name': '旋風奧利奧',
'age': '18',
'hobby': "girl",
'dict': {'drink': '飲品', 'milk': '牛奶'},
'list': ['面包', '包子'],
'object': obj(),
'size': 123456,
'time': datetime.datetime.now()
}
return render(request, "index.html", info)
# return render(request, "index.html", {'info': info})
# html
Title{{ name }}
{{ dict }}
{{ list }}
{{ pdd }}
{% for foo in list %}
{{ foo }}
{% endfor %}
{% for k,v in dict.items %}
{{ k }} : {{ v }}
{% endfor %}
{{ object.obk }}
# url.py
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index)
]
3、Template過濾器
通過過濾器對數據進行過濾處理顯示
使用方式:{{ 變量|過濾器:參數 }}
過濾器支持鏈式操作,通過多個管道符和過濾器相配合實現層級過濾
過濾器可以接收參數
注意事項:管道符左右兩遍不能留空格,否則不能識別;還有參數和:間也不能留空格;
3.1、內置過濾器
(1)default:默認值
?當變量獲取的到值的時候顯示獲取的值,獲取不到值或者獲取的是一個布爾類型的False時就使用默認的default值:{{ value|default:"沒有值"}}
(2)length:長度
?返回的是字符串或列表的長度:{{ value|length }}
(3)filesizeformat:文件大小的顯示處理
?將值格式化為一個 “人類可讀的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。
(4)slice:切片:{{ value|slice:"2:-1" }}
(5)date:時間顯示處理
?對獲取的時間進行過濾處理:{{ value|date:"Y-m-d H:i:s"}}
(6)safe:聲明此變量值(或代碼段)不轉義
{'a_tag':'百度',}
渲染
{{ a_tag|safe }} #生成標簽效果
(7)truncatechars:指定字符串長度,超出部分以 ... 顯示
{{ value|truncatechars:9}}:指定九個字符長度,也包括 ... 這三個字符
(8)truncatewords:以單詞的形式指定字符串長度,超出部分以 ... 顯示
?{{ value|truncatewords:3}}:指三個單詞長度,不包括 ... 部分
(9)cut:過濾字符串
?{{ value|cut:' ' }}:過濾掉value變量中和參數中的空格相同的字符
(10)join:字符串拼接
?{{ hobby|join:'+' }}:把列表數據通過加號拼接成一個字符串
3.2、自定義過濾器
在應用文件夾中創建一個名為templatetags的文件夾(文件夾的名字必須是templatetags)
在templatetags文件夾中創建任意 .py 文件,如:mytag.py
在mytag.py文件中寫上如下內容
from django import template
register = template.Library() # 制作注冊器,名字必須叫register
#過濾最多兩個參數
@register.filter # 注冊過濾器,需要兩個參數的
def add(v1, v2): # v1表示管道符前面的,v2表示冒號后面的參數
print(v1,v2) # 100 50
return v1 + v2
@register.filter # 注冊過濾器,需要一個參數的
def xxx(v1): # v1表示管道符前面的
print(v1)
return 'xxx'
在html文件中導入
{% load mytag %}
Titlebase頁面
{{ num|add:50}}
{{ num|xxx }}
4、Template標簽
?使用方式:{% 標簽 %} {%end標簽%}
4.1、內置標簽
(1)for 循環標簽
?{% for xx in hobby %}{% endfor %}
forloop的使用
?注:循環序號可以通過{{forloop}}顯示,必須在循環內部用
forloop.counter 當前循環的索引值(從1開始),forloop是循環器,通過點來使用功能
forloop.counter0 當前循環的索引值(從0開始)
forloop.revcounter 當前循環的倒序索引值(從1開始)
forloop.revcounter0 當前循環的倒序索引值(從0開始)
forloop.first 當前循環是不是第一次循環(布爾值)
forloop.last 當前循環是不是最后一次循環(布爾值)
forloop.parentloop 本層循環的外層循環的對象,再通過上面的幾個屬性來顯示外層循環的計數等
for循環的反向循環:
?可以利用{% for obj in list reversed %}反向完成循環。
Title{% for i in dict %}
{{ i }}
{% endfor %}
{% for i in dict.values %}
{{ i }}
{% endfor %}
{% for k,v in dict.items %}
{{ k }} : {{ v }}
{% endfor %}
{% for foo in list %}
{{ forloop }} : {{ foo }}
{% endfor %}
{% for foo in list %}
{{ forloop.counter }} : {{ foo }}
{% endfor %}
{% for foo in list %}
{{ forloop.counter0 }} : {{ foo }}
{% endfor %}
{% for foo in list %}
{{ forloop.revcounter }} : {{ foo }}
{% endfor %}
{% for foo in list %}
{{ forloop.revcounter0 }} : {{ foo }}
{% endfor %}
{% for foo in list %}
{{ forloop.first }} : {{ foo }}
{% endfor %}
{% for foo in list %}
{{ forloop.last }} : {{ foo }}
{% endfor %}
{% for foo in list %}
{% for foo in list %}
{{ forloop.parentloop.counter }} : {{ forloop.revcounter0 }} : {{ foo }}
{% endfor %}
{% endfor %}
# 反向循環列表
{% for foo in list reversed %}
{{ foo }}
{% endfor %}
(2)if 判斷標簽
?{% if 判斷條件 %}{% endif %}
if語句支持 and 、or、==、>、=、in、not in、is、is not判斷,注意條件兩邊都有空格。
但是不支持連續判斷操作:{% if a > b > c %}{% endif %}
{% if %}會對一個變量求值,如果它的值是“True”(存在、不為空、且不是boolean類型的false值),對應的內容塊會輸出。
{% if num > 100 or num < 0 %}
無效
{% elif num > 80 and num < 100 %}
優秀
{% else %}
湊活吧
{% endif %}
?
(3)with 起別名標簽
?使用一個簡單地名字緩存一個復雜的變量,多用于給一個復雜的變量起別名,當你需要使用一個“昂貴的”方法(比如訪問數據庫)很多次的時候是非常有用的;注意:等號左右不要加空格。
方式一:
{% with total=business.employees.count %}
{{ total }}
{% endwith %}
方式二:
{% with business.employees.count as total %}
{{ total }}
{% endwith %}
(4)for empty聯合使用的情況
?當循環的hobby沒有數據或為空的時候,就顯示empty下面的內容
{% for xx in hobby %}
{{ xx }}{% empty %}
抱歉,沒有查詢到相關數據
{% endfor %}
(5)Django的模板語言中屬性的優先級大于方法
?處理的字典數據中不要出現以方法名為鍵的鍵值對,因為默認會獲取該鍵值對數據,而不是走方法去處理數據,導致得不到想要的數據結果。
def xx(request):
d = {"a": 1, "b": 2, "c": 3, "items": "100"}
return render(request, "xx.html", {"data": d})
?如上,我們在使用render方法渲染一個頁面的時候,傳的字典d有一個key是items并且還有默認的 d.items() 方法,此時在模板語言中:{{ data.items }}
?默認會取d的items key的值。
4.2、自定義標簽
在應用文件夾中創建一個名為templatetags的文件夾(文件夾的名字必須是templatetags)
在templatetags文件夾中創建任意 .py 文件,如:mytag.py
在mytag.py文件中寫上如下內容
from django import template
register = template.Library() #制作注冊器,名字必須叫register
@register.simple_tag
def atag(v1,v2): #沒有參數個數限制
print(v1,v2)
return v1 + v2
在html文件中導入
{% load mytag %}
Titlebase頁面
{% load mytag %}
{% atag a b %}
5、Templete模板繼承
將一些頁面公共的部分,可以抽離出來單獨做成一個html頁面,使用這些公用部分的其他html文件,只需要繼承一下它就可以了,具體使用流程如下:
(1) 創建公用模板,比如內容如下
Titlebody{
padding: 0;
margin: 0;
}
{% block css %}
.nav{
height: 60px;
background-color: green;
}
{% endblock %}
.nav a{
color:white;
text-decoration: none;
}
.left-menu{
width: 30%;
background-color: rgba(0,0,0,0.5);
float:left;
}
.menu .menu-title{
text-align: center;
}
.main{
float: right;
width: 65%;
height: 300px;
border: 1px solid red;
}
{% block content %}
公共頁面
{% endblock %}
{% block js %}
{% endblock %}
(2)將來如果說繼承公用模板的html文件中需要修改公用模板中的一些內容,那么需要在公用模板中預留一些鉤子,鉤子的寫法如下
{% block content %} #block 后面的塊名稱隨便起
公共頁面
{% endblock %}
#也可以這樣寫 {% endblock content %} #endblock指定名稱
(3)繼承公用模板需要在html文件中寫如下內容:
{% extends 'xx.html' %}
{% block css %}
.nav{
height: 60px;
background-color: pink;
}
{% endblock %}
{% block content %}
首頁
{% endblock %}
(4) 在使用公用模板的其他html文件中,如果需要更改公用模板里面的內容,只需要在html文件中寫上相同的鉤子,鉤子里面寫上自定義的內容,寫法如下
{% block css %}
.nav{
height: 60px;
background-color: pink;
}
{% endblock %}
{% block content %}
首頁
{% endblock %}
(5)注意事項:
如果你在模版中使用 {% extends %} 標簽,它必須是模版中的第一個標簽。其他的任何情況下,模版繼承都將無法工作,模板渲染的時候django都不知道你在干啥。
在base模版中設置越多的 {% block %} 標簽越好。子模版不必定義全部父模版中的blocks,所以,可以在大多數blocks中填充合理的默認內容,然后,只定義你需要的那一個。多一點鉤子總比少一點好。
如果你發現你自己在大量的模版中復制內容,那可能意味著你應該把內容移動到父模版中的一個 {% block %} 中。
{{ block super }}的使用,在子模板中也展示出父模板原來鉤子中的內容
{% block content %}
首頁
{{ block.super }}
{% endblock %}
為了更好的可讀性,你也可以給你的 {% endblock %} 標簽一個 名字 。例如:
{% block content %}
...
{% endblock content %}
在大型模版中,這個方法幫你清楚的看到哪一個 {% block %} 標簽被關閉了。
不能在一個模版中定義多個相同名字的 block 標簽。
#兩個block都叫content,這種寫法是不對的
{% block content %}
首頁
{{ block.super }}
{% endblock %}
{% block content %}
首頁
{{ block.super }}
{% endblock %}
6、要注意Template模板渲染實在瀏覽器解釋之前執行的,模板渲染后才輪到瀏覽器器來執行解釋
7、拓展:XSS攻擊(上面過濾|safe的拓展)
xss攻擊:,全稱跨站腳本攻擊
?Django的模板中在進行模板渲染的時候會對HTML標簽和JS等語法標簽進行自動轉義,原因顯而易見,這樣是為了安全,django擔心這是用戶添加的數據,比如如果有人給你評論的時候寫了一段js代碼,這個評論一提交,js代碼就執行啦,這樣你是不是可以搞一些壞事兒了,寫個彈窗的死循環,瀏覽器就不能用了,瀏覽器會一直彈出彈窗,這叫做xss攻擊,所以瀏覽器中進行了一些轉義處理。但是有的時候我們需要這些HTML元素不被轉義,比如我們做一個內容管理系統,后臺添加的文章中是經過修飾的,這些修飾可能是通過一個類似于FCKeditor編輯加注了HTML修飾符的文本,如果自動轉義的話顯示的就是保護HTML標簽的源文件。為了在Django中關閉HTML的自動轉義有兩種方式,如果是一個單獨的變量我們可以通過過濾器“|safe”的方式告訴Django這段代碼是安全的不必轉義。
http://www.dengb.com/Pythonjc/1413982.htmlwww.dengb.comtruehttp://www.dengb.com/Pythonjc/1413982.htmlTechArticleDjango框架的基本使用,若依框架 Django框架的基本使用 Django是一個功能強大的web框架 框架模式 1、MVC和MTV框架 MVC:Web服務器開發領域里著名...