目錄css
路由:視圖函數的內存地址html
from django .template import Template,Context def func1(request): res = Template('<h1>{{user}}</h>') con=Context({'user':{'username':'zhang','password':123,}}) return HttpResponse(res.render(con))
JsonResponse是HttpResponse的子類,專門用來生成JSON編碼的響應。前端
# ensure_ascii=False 默認等於True,設置成False,遇到中文再也不進行轉碼,僅僅只是進行序列化,轉換成json形式的字符串 import json def func(request): d={'a':1,'b':3,'c':3,'d':4,'e':'速度發貨!!!!!!!'} return HttpResponse(json.dumps(d,ensure_ascii=False),) #
from django.http import JsonResponse def func(request): d={'a':1,'b':3,'c':3,'d':4,'e':'速度發貨!!!!!!!'} l=[1,2,3,4,5,] # return JsonResponse(d) # 加括號是個對象,內部也是基於json.dumps進行的序列化,默認遇到中文也會轉成ASCII編碼, # return JsonResponse(d,json_dumps_params={'ensure_ascii':False}) # 遇到中文不轉碼 return JsonResponse(l,safe=False) # In order to allow non-dict objects to be serialized set the safe parameter to False. 根據報錯信息,去源碼找到JsonResponse不能序列化其餘數據類型的緣由,就是修改safe=True 爲False,以後就能序列化其餘數據類型(json模塊能序列化的)了
咱們以前寫過的都是基於函數的view,就叫FBV。還能夠把view寫成基於類的。
FBV:基於函數的視圖
CBV:基於類的視圖python
from django.views import View class MyLogin(View): def get(self,request): print('我是MyLogin裏面的get方法') return render(request,'login.html') def post(self,request): print('我是MyLogin裏面的post方法') return HttpResponse('post') # 路由的書寫 與CBV有點不一樣 # FBV寫法 路由 >>> 視圖函數內存地址 url(r'^index/',views.index), # CBV寫法 url(r'^login/',views.MyLogin.as_view()) # views.view 本質也是FBV
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] def http_method_not_allowed(self, request, *args, **kwargs): logger.warning( 'Method Not Allowed (%s): %s', request.method, request.path, extra={'status_code': 405, 'request': request} ) return http.HttpResponseNotAllowed(self._allowed_methods()) @classonlymethod def as_view(cls, **initkwargs): def view(request, *args, **kwargs): # 閉包函數 self = cls(**initkwargs) # cls是咱們本身寫的類 MyLogin self是咱們本身定義的類的對象 # 在看源碼的時候 你必定要把握住一個順序 對象在查找屬性和方法的時候 # 先從對象自身找 再去產生對象的類中找 再去類的父類中找 return self.dispatch(request, *args, **kwargs) return view def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. # 判斷當前請求方式在不在默認的八個方法內 # 1.先以GET請求爲例 if request.method.lower() in self.http_method_names: # 利用反射去咱們本身定義類的對象中查找get屬性或者是方法 getattr(obj,'get') # handler = get方法 handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) # 調用get方法
使用裝飾器裝飾FBV
FBV自己就是一個函數,因此和給普通的函數加裝飾器無差:jquery
def wrapper(func): def inner(*args, **kwargs): start_time = time.time() ret = func(*args, **kwargs) end_time = time.time() print("used:", end_time-start_time) return ret return inner # FBV版添加班級 @wrapper def add_class(request): if request.method == "POST": class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") return render(request, "add_class.html")
CBV 加裝飾器的方式django
類中的方法與獨立函數不徹底相同,所以不能直接將函數裝飾器應用於類中的方法 ,咱們須要先將其轉換爲方法裝飾器。json
Django中提供了method_decorator裝飾器用於將函數裝飾器轉換爲方法裝飾器bootstrap
#使用CBV時要注意,請求過來後會先執行dispatch()這個方法,若是須要批量對具體的請求處理方法,如get,post等作一些操做的時候,這裏咱們能夠手動改寫dispatch方法,這個dispatch方法就和在FBV上加裝飾器的效果同樣。後端
給CBV加裝飾器 推薦你使用內置模塊 from django.utils.decorators import method_decorator # 2.能夠指定給誰裝 # @method_decorator(wrapper,name='post') # name=... 表示指定給誰裝 # @method_decorator(wrapper,name='dispatch') class MyLogin(View): @method_decorator(wrapper) def dispatch(self, request, *args, **kwargs): # 若是你想在視圖函數執行以前 作一些操做 你能夠在你的CBV中定義dispatch方法來攔截 return super().dispatch(request,*args,**kwargs) # @outter # 1.直接寫 # @method_decorator(outter) # 1.推薦寫法 def get(self,request): print('我是MyLogin裏面的get方法') return render(request,'login.html') # @outter def post(self,request): print('我是MyLogin裏面的post方法') time.sleep(1) return HttpResponse('post')
只有兩種書寫格式: {{}} 變量相關 {%%} 邏輯相關 模板傳值:python基本數據類型所有支持傳值
在Django的模板語言中按此語法使用:{{ 變量名 }}。閉包
當模版引擎遇到一個變量,它將計算這個變量,而後用結果替換掉它自己。 變量的命名包括任何字母數字以及下劃線 ("_")的組合。 變量名稱中不能有空格或標點符號。
點(.)在模板語言中有特殊的含義。當模版系統遇到點("."),它將以這樣的順序查詢:
字典查詢(Dictionary lookup)
屬性或方法查詢(Attribute or method lookup)
數字索引查詢(Numeric index lookup)
注意事項:
# test.py文件 def test(request): n=1 f=1.11 s='hello baby~' l=[1,2,3,4,] t=(1,2,3,44,55) d={'name':'zhangsan','hobby':'read'} se={12,13,14,15,} b=False def index1(): #給HTML頁面傳遞函數名的時候 模板語法會自動加括號調用該函數 而且將函數的返回值當作展現依據,模板語法不支持函數傳參 也就意味着 你傳給html頁面的只能是不須要傳參調用的函數 return '都是廢話' class Test(object): def get_self(self): return 'get_self' obj = Test() return render(request,'test.html',locals()) # 傳類名像函數名同樣,也是加括號調用,實例化一個對象;傳對象,就是對象自己,是類的對象的內存地址;只要是可以加括號調用的 傳遞到html頁面上都會自動加括號調用
<!--test.html文件--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <p>{{ n }}</p> <p>{{ f }}</p> <p>{{ s }}</p> <p>{{ l }}</p> <p>{{ se }}</p> <p>{{ d }}</p> <p>{{ b }}</p> <p>傳函數名:{{ index1 }}</p> <p>傳函數名:{{ Test }}</p> <p>傳函數名:{{ obj }}</p> </body> </html>
模板語法也給你提供了一些內置的方法 幫你快速的處理數據
過濾器的語法: {{ value|filter_name:參數 }}
例如:{{ name|lower }}會將name變量應用lower過濾器以後再顯示它的值。lower在這裏的做用是將文本全都變成小寫。
注意事項:
1.過濾器支持「鏈式」操做。即一個過濾器的輸出做爲另外一個過濾器的輸入。
2.過濾器能夠接受參數,例如:{{ sss|truncatewords:30 }},這將顯示sss的前30個詞。
3.過濾器參數包含空格的話,必須用引號包裹起來。好比使用逗號和空格去鏈接一個列表中的元素,如:{{ list|join:', ' }}
4.'|'左右沒有空格沒有空格沒有空格
先後端取消轉義(*)
前端 |safe 後端 from django.utils.safestring import mark_safe sss2 = "<h2>個人h2標籤</h2>" res = mark_safe(sss2)
<p>統計長度(若是沒法統計默認返回0):{{ s|length }}</p> <p>加法運算(內部異常捕獲 支持數字相加 字符串拼接 都不符合返回空):{{ n|add:f }}</p> <p>切片操做 顧頭不顧尾 也支持步長:{{ l|slice:'0:5:2' }}</p> <p>判斷是否有值(有值展現值自己 沒值展現默認值):{{ is_value|default:'is_value變量名指向的值爲空' }}</p> <p>自動轉成文件大小格式:{{ file_size|filesizeformat }}</p> <p>截取文本內容(字符) 截取五個字符 三個點也算:{{ s|truncatechars:8 }}</p> <p>截取文本內容(按照空格計算) 截取五個字符 三個點不算 :{{ s1|truncatewords:5 }}</p> <p>默認狀況下,不會轉換成前端html標籤 :{{sss}}</p> # 後端傳來的字符串類型的標籤 <p>展現帶有標籤的文本:{{ sss|safe }}</p> 添加safe參數以後能夠轉換後端傳來的字符串標籤 <p>展現帶有標籤的文本:{{ ss|safe }}</p> 後端: ss='<script>alert(123)</script>'
標籤 邏輯相關
if
for循環
{% for foo in l %} {{ forloop }} {% if forloop.first %} <p>{{ foo }}</p> {% elif forloop.last %} {% else %} <p>{{ foo }}</p> {% endif %} {% empty %} <p>檔for循環的對象爲空的時候走這個!</p> {% endfor %}
模板語法的取值 只有一種方式 統一採用句點符 (.)
<p>{{ comp_dic.hobby.2.2.age }}</p>
<p>當你的數據是經過比較複雜的點點點獲取到的後續又須要常用 你能夠給該數據起別名 別名只能在with內部使用</p> {% with comp_dic.hobby.2.2.age as age %} <p>{{ age }}</p> <p>{{ comp_dic.hobby.2.2.age }}</p> {% endwith %}
django支持用戶自定義
必需要先有三部準備
1.在應用名下新建一個名字必須叫templatetags的文件夾
2.在該文件夾內 新建一個任意名稱的py文件
3.在該py文件中 必須先寫下面兩句代碼
from django.template import Library
register = Library()
以後就能夠利用register來自定義過濾器和標籤
# 應用名下templatetag文件夾 mytag.py文件 from django.template import Library register = Library() # 自定義過濾器,跟默認的過濾器同樣,最多隻能接受兩個參數 @register.filter(name='xxx') # 給過濾器起名字 def index(a,b): return a+b
使用自定義的過濾器,須要先在html頁面上 加載。
<!--test.html文件--> {% load mytag %} {{ 1|xxx:99 }}
# 應用名下templatetag文件夾 mytag.py文件 # 自定義標籤 能夠接受任意多個參數 @register.simple_tag(name='zzz') def mytag(a,b,c,d): return '%s?%s?%s?%s'%(a,b,c,d)
<!--test.html文件--> {% load mytag %} {% zzz 'a' 'b' 'c' 'd' %}
<!--test.html文件--> <p>自定義的過濾器能夠在邏輯語句使用 而自定義的標籤不能夠</p> {% if 1|xxx:99 %} <p>有值</p> {% else %} <p>無值</p> {% endif %}
是一個函數 可以接受外界傳入的參數, 而後傳遞給一個html頁面,頁面上獲取數據 渲染完成以後,將渲染好的頁面放到調用inclusion_tag的地方
# 應用名下templatetag文件夾 mytag.py文件 # 自定義inclusion_tag @register.inclusion_tag('mytag.html',name='xxx') def index666(n): l = [] for i in range(n): l.append('第%s項'%i) return locals() # 將l直接傳遞給mytag.html頁面
<!--mytag.html文件--> <!--只作臨時渲染的頁面,因此該頁面的其餘框架部分html代碼就不須要了--> <ul> {% for foo in l %} <li>{{ foo }}</li> {% endfor %} </ul>
<!--test.html文件--> <p>自定義inclusion_tag的使用 當你須要使用一些頁面組件的時候 而且該頁面組件須要參數纔可以正常渲染 你能夠考慮使用inclusion_tag</p> {% load mytag %} {% xxx 5 %}
你須要事先在你想要使用的頁面上劃定區域,以後在繼承的時候 ,你就可使用你劃定的區域,也就意味着,若是你不劃定任何區域,那麼你將沒法修改頁面內容。
<!--先在頁面上利用block劃定你之後可能想改的區域--> {% block content %} {% endblock %} <!--繼承以後 就能夠經過名字找到對應的區域進行修改--> {% extends 'home.html' %} {% block content %} <!--修改模板中content區域內容--> {% endblock %}
模板上的block區域越多 頁面的擴展性越強 建議你一個模板頁面至少有三塊區域: css區域 html代碼區域 能夠設置多個block js區域 有了這三塊區域 就可以實現每個頁面都有本身獨立的css和js代碼
{% extends 'home.html' %} 子文件就能夠經過這個方法繼承豬文件的html代碼的格式 {% block css %} <style> p { color: green; } </style> {% endblock %} {% block content %} <p>login頁面</p> {% endblock %} {% block js %} <script> alert('login') </script> {% endblock %} 你還能夠在子頁面上繼續沿用父頁面的內容 {{ block.super }}
模板的繼承
1.先在你想要繼承的頁面上經過block劃定你未來可能要改的區域
2.在子頁面上先繼承extends
3.利用block自動提示 選擇你想要修改的內容區域
將html頁面當作模塊的直接導入使用 {% include 'bform.html' %}