小白必會三板斧css
HttpResponsehtml
render前端
redirectpython
視圖函數必須有一個返回值 而且返回值的數據類型必須是HttpResponse對象django
JsonResponsejson
先後端分離後端
先後端數據交互 該如何進行?瀏覽器
一般狀況下先後端的數據交互採用的都是json的字符串(字典)前端工程師
後端只須要寫好相應的url接口 前端訪問你這個接口閉包
你只須要返回一個大字典便可+開發文檔
用來告訴前端工程師 你這個接口可以返回那些數據
先後端序列化都用哪些方法
python後端 js
json.dumps JSON.stringify
json.loads JSON.parse
def index(request): user_dic = {'name':'jason好帥哦 我好喜歡~','password':'123'} # 如何讓json不自動幫你對中文進行轉碼,把ensure_ascii設置爲false,默認的是true # json_str = json.dumps(user_dic,ensure_ascii=False) # return HttpResponse(json_str) # return JsonResponse(user_dic,json_dumps_params={'ensure_ascii':False}) l = [1,2,3,4,5,6,7,] #若是容器類型數據爲空的時候 不執行任何語句 # JsonResponse默認是序列化字典用的 若是你想序列化其餘數據類型(json模塊可以序列化的) 你須要加一個safe參數 return JsonResponse(l,safe=False)
FBV與CBV
FBV:是基於函數視圖
CBV:是基於類的視圖
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())
CBV的源碼
爲何CBV可以根據請求的不一樣 自動執行不一樣的方法?
訪問屬性和方法
方法就是函數(函數名加括號執行優先級最高)url(r'^login/',views.MyLogin.as_view()
)
項目一啓動 會自動執行as_view
方法
CBV在路由上匹配 其實本質就是FBV 路由 >>>>視圖函數內存地址
# CBV寫法 url(r'^login/',views.MyLogin.as_view()), # url(r'^login/',views.view) # 訪問屬性和方法 # 方法就是函數(函數名加括號執行優先級最高) # 項目一啓動 會自動執行as_view方法 # views.test和上面登陸的views.view本質上寫法是同樣的,CBV在路由匹配上 其實本質仍是FBV 路由 >>> 視圖函數內存地址 url(r'^test/',views.test), url(r'^index/',views.index),#index在匹配上路由的時候觸發 url(r'^login/',views.MyLogin.as_view()),#在瀏覽器上出入login就會觸發 # 若是在urls中設置url(r'',home),會截獲全部的url,若是放在文件的下面不截獲 #網站首頁可使用url(r'^$',home) #訪問網站404頁面的設計 url(r'',error)
@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 #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方法
給CBV加裝飾器 推薦使用內置模塊 from django.utils.decorators import method_decorator ======2.能夠指定給誰裝====== #@method_decorator(outter,name='post') #@method_decorator(outter,name='dispatch') class MyLogin(View): @method_decorator(outter) 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基本數據類型所有支持傳值
<p> 傳函數名{{index}} 給html頁面傳遞函數名的時候 模板語法會自動加括號調用函數 而且將函數的返回值當作展現依據 模板語法不支持函數傳參 也就意味着 你傳給html頁面的只能是不須要傳參調用的函數 </p> <p>傳類名:{{MyClass}} </p> <p>{{ obj.get_self }}</p> <p>{{ obj.get_cls }}</p> <p>{{ obj.get_func }}</p> <p>只要是可以加括號調用的 傳遞到html頁面上的都會自動的加貨號調用</p1> 給html頁面傳值的兩種方式 第一種 指名道姓 當須要傳遞的變量名特別多的狀況下 有點麻煩 return render(request,'test.html',{'n':n}) 第二種 locals() 會將當前所在的名稱空間中全部的名字 所有傳遞給html頁面 return render(request,'test.html',locals())
過濾器
語法結構
模板語法也給你提供了一些的內置的方法 幫你快速的提供處理數據的能力
最可能是兩個參數
前端的取消轉義
|false
後端
from django.utils.safestring import mark_safe
sss2 = "<h2>個人h2標籤</h2>"
res = mark_safe(sss2)
<p> 模板語法之過濾器 會自動將|左邊的數據當前過濾器的第一個參數 傳入 :右邊的當作第二個參數</p> {<p>統計長度(若是沒法統計默認返回0):{{s|length}}</p>} {<p>加法運算(內部異常捕獲 支持數字相加 字符串拼接 都不符合返回空):{{n|add:f}}</p>} {<p>切片操做 顧頭不顧尾 也支持步長 :{{l|slice:'0:5:3'}}</p>} {<p>判斷是否有值 (有值展現值的自己 沒有值展現默認的值):{{ is_value|default:'is_value變量名指向的值爲空' }}</p>} {<p>自動轉成文件大小的格式:{{file_size |filtesizeformat}}</p>} {<p>截取文件的內容(字符) 截取五個字符 後面的三個點也算:{{ s|truncatechars:8 }}</p>} {<p>截取文本的內容(按照空格計算) 截取五個單詞 三個點不算:{{s1|truncatewords:5}}</p>} {<p>默認狀況下 是不會自動幫你轉換成前端的html標籤的 防止惡意攻擊</p>} {<p>展現帶有標籤的文本:{{sss|safe}}</p>} {<p>展現帶有標籤的文本:{{sss1|safe}}</p>}
標籤
邏輯相關的
if
for循環
for if聯合使用 {% for foo in l %} {% if forloop.first %} <p>這是個人第一次</p> {% elif forloop.last %} <p>這是最後一次了啊</p> {% else %} <p>{{ foo }}</p> {% endif %} {% empty %} <p>當for循環的對象是空的時候會走</p> {% endfor %} <p>模板語法的取值 只有一種方式 統一採用點(.)的方式</p> <p>{{ comp_dic.hobby.2.2.age }}</p> 當你的數據是經過比較複雜的點點點獲取到的後續又須要常用 你能夠給該數據起別名 別名只能在with內部使用 {% with comp_dic.hoby.2.2.age as age %} <p>{{age}}</p> <p>{{ comp_dic.hoby.2.2.age}}</p> {% endwith%}
自定義過濾器和標籤
django支持用戶自定義
必需要先有三步準備
1.在應用名下新建一個名字必須是templatetags文件夾
2.在該文件夾內 新建一個任意名稱的py文件
3.在該文件中 必須先寫下面的兩句代碼
from django.template import Library
register = Library()
以後就能夠利用register來自定義過濾器和標籤
使用自定義的過濾器
須要先在html頁面上 加載
自定義過濾器 跟默認的過濾器同樣 最多隻能接受兩個參數
@register.filter(name='baby') def index(a,b) return a+b
自定義標籤
自定義的標籤能夠接受任意多個參數
@register.simple_tag(name='mytag') def mytag(a,b,c,d): return '%s?%s?%s?%s?'%(a,b,c,d)
自定義inclusion_tag
是一個函數 可以接受外界傳入的參數 而後傳遞給一個html頁面
頁面上獲取的數據 渲染 完成以後
將渲染好的頁面 放到調用inclusion_tag 的地方
自定義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頁面 {#<p>自定義過濾器的使用</p>#} {#{% load mytag %}#} {#{{ 1|baby:1 }}#} {#{{ 1|baby:100 }}#} 自定義標籤的使用 能夠接受多個參數 參數之間必須空格隔開 {#{% load mytag %}#} {#{% mytag 'a' 'b' 'c' 'd' %}#} {#{% load mytag %}#} 自定義的過濾器能夠在邏輯語句使用 而自定義的標籤不能夠 {#{% if mytag '1' '2' '3' '4' %}#} {# <p>有值</p>#} {# {% else %}#} {# <p>無值</p>#} {#{% endif %}#} 自定義inclusion_tag 的使用 當你須要使用一些頁面組件的時候 而且該頁面組件須要參數纔可以正常渲染 你能夠考慮使用inclusion_tag {% load mytag %} {% xxx 5 %} 標籤 邏輯相關 索引:'counter0':0 計數:'counter':1 可以判斷for循環的開始:'first':True 可以判斷for循環的結束:'last':True
模板繼承
你須要事先在你想要使用的頁面上 劃定區域 以後在繼承的時候 你就可使用你劃定的區域
也就意味着 若是你不劃定任何區域 那麼你就將沒法修改頁面上的內容
{% block content %} {% endlock %} 先在頁面上利用block劃定你之後可能想改的區域 繼承以後 就能夠經過名字找到對應的區域進行修改 {% extends 'home.html'%} {% block content %} 修改模板中content區域內容 {% endblock %} 模板上的block區域越多 頁面的擴展性越高 建議你一個模板頁面至少有三塊區域 css區域 html代碼區域 能夠設置多個block js區域 有了這三塊區域 就能實現每個頁面都有本身獨立的css和js代碼 {% extends 'home.html' %} {% block css %} <style> p { color: green; } </style> {% endblock %} {% block content %} <p>login頁面</p> {% endblock %} {% block js %} <script> alert('login') </script> {% endblock %} 你還能夠在子頁面上繼續沿着父頁面的內容 {{ block.super }} 模板的繼承 先在你想要繼承的頁面上經過block劃定你將要改動的區域 在子頁面上先繼承extends 利用block自動提示 選擇你想要修改的內容的區域
模板導入
將html頁面當作模塊的直接導入使用
{% include 'bform.html' %}
靜態文件目錄路徑
STATICFILES_DIRS = [os.path.join(BASE_DIR,'static')]