""" 視圖函數便可以是函數也能夠是類 """ # FBV def index(request): return HttpResponse('OK') # CBV from django.views import View """只要是處理業務邏輯的視圖函數 形參裏面確定要有request""" class MyClass(View): def get(self,request): return HttpResponse('get請求') def post(self,request): return HttpResponse('post請求') # 注意 CBV路由匹配寫法跟FBV有點不同(可是其實本質是同樣的) url(r'^login/$',views.MyClass.as_view()) # 疑問:CBV可以作到根據不一樣的請求方式自動匹配對應的方法並執行???(******)
# 你本身不要修改源碼 除了bug很難找 # 突破口在urls.py url(r'^login/',views.MyLogin.as_view()) # url(r'^login/',views.view) FBV如出一轍 # CBV與FBV在路由匹配上本質是同樣的 都是路由 對應 函數內存地址 """ 函數名/方法名 加括號執行優先級最高 猜想 as_view() 要麼是被@staicmethod修飾的靜態方法 要麼是被@classmethod修飾的類方法 正確 @classonlymethod def as_view(cls, **initkwargs): pass """ @classonlymethod def as_view(cls, **initkwargs): """ cls就是咱們本身寫的類 MyCBV Main entry point for a request-response process. """ def view(request, *args, **kwargs): self = cls(**initkwargs) # cls是咱們本身寫的類 # self = MyLogin(**initkwargs) 產生一個咱們本身寫的類的對象 return self.dispatch(request, *args, **kwargs) """ 之後大家會常常須要看源碼 可是在看python源碼的時候 必定要時刻提醒本身面向對象屬性方法查找順序 先從對象本身找 再去產生對象的類裏面找 以後再去父類找 ... 總結:看源碼只要看到了self點一個東西 必定要問你本身當前這個self究竟是誰 """ return view # CBV的精髓 def dispatch(self, request, *args, **kwargs): # 獲取當前請求的小寫格式 而後比對當前請求方式是否合法 # get請求爲例 # post請求 if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) """ 反射:經過字符串來操做對象的屬性或者方法 handler = getattr(本身寫的類產生的對象,'get',當找不到get屬性或者方法的時候就會用第三個參數)
###### getattr 就等同於 self.reques.method.lower() handler = 咱們本身寫的類裏面的get方法 """ else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) """ 自動調用get方法 """ # 要求掌握到不看源碼也可以描述出CBV的內部執行流程(******)
{{ }}:變量相關css
{% %}:邏輯相關 html
def index(request): # 模版語法能夠傳遞的後端python數據類型 n = 123 f = 11.11 s = '我也想奔現' b = True l = ['小紅','姍姍','花花','茹茹'] t = (111,222,333,444) d = {'username':'jason','age':18,'info':'這我的有點意思'} se = {'晶晶','洋洋','嚶嚶'} def func(): print('我被執行了') return '你的另外一半在等你' class MyClass(object): def get_self(self): return 'self' @staticmethod def get_func(): return 'func' @classmethod def get_class(cls): return 'cls' # 對象被展現到html頁面上 就相似於執行了打印操做也會觸發__str__方法 def __str__(self): return '到底會不會?' obj = MyClass() # return render(request,'index.html',{}) # 一個個傳 return render(request,'index.html',locals()) <p>{{ n }}</p> <p>{{ f }}</p> <p>{{ s }}</p> <p>{{ b }}</p> <p>{{ l }}</p> <p>{{ d }}</p> <p>{{ t }}</p> <p>{{ se }}</p> <p>傳遞函數名會自動加括號調用 可是模版語法不支持給函數傳額外的參數:{{ func }}</p> <p>傳類名的時候也會自動加括號調用(實例化){{ MyClass }}</p> <p>內部可以自動判斷出當前的變量名是否能夠加括號調用 若是能夠就會自動執行 針對的是函數名和類名</p> <p>{{ obj }}</p> <p>{{ obj.get_self }}</p> <p>{{ obj.get_func }}</p> <p>{{ obj.get_class }}</p> # django模版語法的取值 是固定的格式 只能採用「句點符」 . <p>{{ d.username }}</p> <p>{{ l.0 }}</p> <p>{{ d.hobby.3.info }}</p> # 便可以點鍵也能夠點索引 還能夠二者混用
# 過濾器就相似因而模版語法內置的 內置方法 # django內置有60多個過濾器 咱們不須要學這麼多 瞭解10個左右就差很少了 後面碰到了再去記憶 def index(request): n = 123 f = 11.11 s = '我也想奔現' b = True l = ['小紅', '姍姍', '花花', '茹茹'] t = (111, 222, 333, 444) d = {'username': 'jason', 'age': 18, 'info': '這我的有點意思'} se = {'晶晶', '洋洋', '嚶嚶'} file_size = 1230214 import datetime current_time = datetime.datetime.now() info = '啊是 的撒 打算 蔣 經 國迪斯科浪費口水都快的' egl = 'my name is egon i am very handsom' obj = MyClass() hhh = '<h1>唐嫣</h1>' sss = '<script>alert(123)</script>' from django.utils.safestring import mark_safe res = mark_safe('<h1>林允兒</h1>') ####### 基本語法 {{數據|過濾器:參數}} ###### 轉義 # 前端 {{ 數據|safe }} # 後端 from django.utils.safestring import mark_safe res = mark_safe('<h1>新新</h1>') """ 之後你在全棧項目的時候 前端代碼不必定非要在前端頁面書寫 也能夠如今先在後端寫好 而後傳遞給前端頁面 """ <h1>過濾器</h1> <p>統計長度:{{ s|length }}</p> <p>默認值(第一個參數布爾值是True就展現第一個參數的值否在展現冒號後面的值):{{ b|default:'啥也不是' }}</p> <p>文件大小:{{ file_size|filesizeformat }}</p> <p>日期格式化:{{ current_time|date:'Y-m-d H:i:s' }}</p> <p>切片操做(支持步長):{{ l|slice:'0:4:2' }}</p> <p>切取字符(包含三個點):{{ info|truncatechars:9 }}</p> <p>切取單詞(不包含三個點 按照空格切):{{ egl|truncatewords:9 }}</p> <p>切取單詞(不包含三個點 按照空格切):{{ info|truncatewords:9 }}</p> <p>移除特定的字符:{{ msg|cut:' ' }}</p> <p>拼接操做:{{ l|join:'$' }}</p> <p>拼接操做(加法):{{ n|add:10 }}</p> <p>拼接操做(加法):{{ s|add:msg }}</p> <p>轉義:{{ hhh|safe }}</p> <p>轉義:{{ sss|safe }}</p> <p>轉義:{{ res }}</p>
標籤其實就是一堆邏輯,好比for循環,if判斷等前端
# for循環 {% for foo in l %} <p>{{ forloop }}</p> <p>{{ foo }}</p> 一個個元素 {% endfor %} {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': True, 'last': False} # if判斷 {% if b %} <p>baby</p> {% elif s%} <p>都來把</p> {% else %} <p>老baby</p> {% endif %} # for與if混合使用 {% for foo in lll %} {% if forloop.first %} <p>這是個人第一次</p> {% elif forloop.last %} <p>這是最後一次啊</p> {% else %} <p>{{ foo }}</p> {% endif %} {% empty %} <p>for循環的可迭代對象內部沒有元素 根本無法循環</p> {% endfor %} # 處理字典其餘方法 {% for foo in d.keys %} <p>{{ foo }}</p> {% endfor %}
{% for foo in d.values %} <p>{{ foo }}</p> {% endfor %}
{% for foo in d.items %} <p>{{ foo }}</p> {% endfor %} # with 起別名(名字太長一直輸太麻煩,起個簡短的別名方便操做) {% with d.hobby.3.info as nb %} <p>{{ nb }}</p> 在with語法內就能夠經過as後面的別名快速的使用到前面很是複雜獲取數據的方式 <p>{{ d.hobby.3.info }}</p> {% endwith %}
這三個的使用前提,三步走
1.在應用下建立一個名字」必須「叫templatetags文件夾 2.在該文件夾內建立「任意」名稱的py文件 eg:mytag.py 3.在該py文件內"必須"先書寫下面兩句話(單詞一個都不能錯) from django import template register = template.Library()
from django import template
register = template.Library()
# 自定義過濾器(參數最多倆個) @register.filter(name='baby') def my_sum(v1, v2): return v1 + v2 # 使用 {% load mytag %} <p>{{ n|baby:666 }}</p> # 自定義標籤(參數能夠有多個) 相似於自定義函數 @register.simple_tag(name='plus') def index(a,b,c,d): return '%s-%s-%s-%s'%(a,b,c,d) # 使用 標籤多個參數彼此之間空格隔開 <p>{% plus 'jason' 123 'egon' 123 %}</p> # 自定義inclusion_tag """ 內部原理 先定義一個方法 在頁面上調用該方法 而且能夠傳值 該方法會生成一些數據而後傳遞給一個html頁面 以後將渲染好的結果放到調用的位置 """ @register.inclusion_tag('left_menu.html') def left(n): data = ['第{}項'.format(i) for i in range(n)] # 第一種 # return {'data':data} # 將data傳遞給left_menu.html # 第二種 return locals() # 將data傳遞給left_menu.html
{% load mytag %} {% left 5 %} # 總結:當html頁面某一個地方的頁面須要傳參數纔可以動態的渲染出來,而且在多個頁面上都須要使用到該局部 那麼就考慮將該局部頁面作成inclusion_tag形式 (在bbs的時候會使用到)
""" 大家有沒有見過一些網站 這些網站頁面總體都大差不差 只是某一些局部在作變化 """ # 模版的繼承 你本身先選好一個你要想繼承的模版頁面 {% extends 'home.html' %} # 繼承了以後子頁面跟模版頁面長的是如出一轍的 你須要在模版頁面上提早劃定能夠被修改的區域 {% block content %} 模版內容 {% endblock %} # 子頁面就能夠聲明想要修改哪塊劃定了的區域 {% block content %} 子頁面內容 {% endblock %} # 通常狀況下模版頁面上應該至少有三塊能夠被修改的區域 1.css區域 2.html區域 3.js區域 {% block css %} {% endblock %} {% block content %} {% endblock %} {% block js %} {% endblock %} # 每個子頁面就均可以有本身獨有的css代碼 html代碼 js代碼 """ 通常狀況下 模版的頁面上劃定的區域越多 那麼該模版的擴展性就越高 可是若是太多 那還不如本身直接寫 """
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>圖書館管理系統</title> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> {% block css %} {% endblock %} <body> <nav class="navbar navbar-inverse"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div class="container-fluid"> <div class="row"> <div class="col-md-3"> <div class="list-group"> <a href="/home/" class="list-group-item active"> 首頁 </a> <a href="/login/" class="list-group-item">登陸</a> <a href="/register/" class="list-group-item">註冊</a> </div> </div> <div class="col-md-9"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">Panel title</h3> </div> <div class="panel-body"> {% block aaa %} <div class="jumbotron"> <h1>Hello, world!</h1> <p>...</p> <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p> </div> {% endblock %} </div> </div> </div> </div> </div> {% block js %} {% endblock %} </body> </html>
{% extends 'home.html' %} {% block css %} <style> h1 { color: red; } </style> {% endblock %} {% block aaa %} <h1 class="text-center">登錄頁面</h1> <form action=""> <p>username: <input type="text" name="username" class="form-control"></p> <p>password: <input type="password" name="password" class="form-control"></p> <input type="submit" class="btn btn-primary btn-block"> </form> {% endblock %} {% block js %} <script> alert('登錄頁面') </script> {% endblock %}
{% extends 'home.html' %} {% block css %} <style> h1 { color: greenyellow; } </style> {% endblock %} {% block aaa %} <h1 class="text-center">註冊頁面</h1> <form action=""> <p>username: <input type="text" name="username" class="form-control"></p> <p>password: <input type="password" name="password" class="form-control"></p> <input type="submit" class="btn btn-success btn-block"> </form> {% endblock %} {% block js %} <script> alert('註冊頁面') </script> {% endblock %}
""" 將頁面的某一個局部當成模塊的形式 哪一個地方須要就能夠直接導入使用便可 """ {% include 'wasai.html' %}
1.什麼是FBV與CBV,能不能試着解釋一下CBV的運做原理 2.模版語法的傳值須要注意什麼,常見過濾器及標籤有哪些 3.自定義過濾器,標籤,inclusion_tag的流程 4.什麼是模版的繼承與導入,如何正確使用
# 可以根據請求方式的不一樣自動匹配觸發對應的方法的執行(只要是視圖函數都應該有一個形參request) # url FBV與CBV在路由匹配上本質是同樣的都是路由對應函數內存地址 url(r'^index/',views.index) url(r'^login/',views.MyClass.as_view()) # url(r'^login/',views.view) # 源碼 MyClass.as_view() @classonlymethod def as_view(cls,**initkwargs): def view(*args,**kwargs): self = cls(*args,**kwargs) ... return self.dispatch(*args,**kwargs) """ 你在後面看python源碼的時候 只要看到self點東西 你必定要問你本身一些當前這個self究竟是誰??? 屬性方法查找順序 對象自己找 產生對象的類中 類的父類們 """ return view def dispatch(*args,**kwargs): if request.method.lower() in ['get','post',...]: handler = getattr(self,request.method.lower(),'報錯信息') else: handler = '報錯提示方法' return handler(request,*args,**kwargs)
變量相關:{{}}python
邏輯相關:{%%}jquery
# 你要知道render支持兩種給html文件傳值的方式 # python全部的基本數據類型 函數名 類名 對象均可以被傳到html上 # 針對函數名和類名 模版語法會自動加括號調用(可是不支持傳遞額外的參數) # 模版語法如何獲取容器類型裏面的數據 統一採用句點符 . .key .index .key.index.index.key
# 語法結構 最多隻能有兩個參數 {{ data|過濾器:'參數'}} |length |default |filesizeformat |date:'Y-m-d' |slice:'0:6:2' |truncatechars(包含三個點) |truncatewords(不包含三個點 按空格切) |add |cut |join |safe 轉義 # 前端 |safe # 後端 from django.utils.safestring import mark_safe res = mark_safe('<h1>baby</h1>') """ 前端代碼不必定非要在html頁面上書寫,也能夠在後端生成而後傳遞給html頁面!!! """
# for循環 {% for i in l %} {{ forloop }} {% empty %} 可迭代對象裏面沒有元素 無法for循環的時候自動走empty {% endfor %} counter counter0 first last # if判斷 {% if user %} {% elif age %} {% else %} {% endif %} # with起別名 {% with data.0.name.1.password.2.heiheihei as t%} {{ t }} {%endwith%} # 模版語法也支持對字典獲取鍵 值 鍵值對操做 .keys .values .items
""" 1.在對應的應用下建立一個名字必須叫templatetags文件夾 2.該文件夾內建立一個任意名稱的py文件 mytag.py 3.在該py文件內須要先書寫兩句固定的代碼 from django import template register = template.Library() """ # 自定義過濾器 @register.filter(name='過濾器的名字') def index(v1,v2): return v1 + v2 # 自定義標籤 @register.simple_tag(name='標籤的名字') def func(*args): pass # 自定義inclusion_tag @register.inclusion_tag('html文件名') def bar(n): return locals() # 傳數據方式1 return {} # 傳數據方式2 # 如何使用上述三者 {% load mytag %} {{ data|過濾器的名字:'參數' }} {% 標籤的名字 參數1 參數2 參數3 參數4%} {% bar %}
""" 同一個html頁面 想重複的使用大部分樣式 只是局部修改 """ # 繼承 {% extends '模版頁面名' %} # 局部修改 # 1.你須要先去模版頁面中劃定能夠被修改的區域 {% block '名字' %} 模版內容(666) {% endblock %} # 2.子頁面中即成了模版頁面以後 就能夠根據名字修改 {% block '名字' %} 子版內容 子版頁面吃了能夠本身寫本身的以外 還能夠繼續使用模版的內容 {{ block.super }} 666 {{ block.super }} 666 {{ block.super }} 666 {{ block.super }} 666 {% endblock %} # 規律:通常狀況下模版頁面內至少應該有三塊區域 css html js 全部的子頁面中 均可以有本身獨立的css html 和js # 利用模版的繼承 可以讓你的頁面更加的好維護
{% include '模版文件名' %}ajax
""" 必作題 1.整理今日內容,用本身的話術和思路整理到我的博客中 2.閱讀CBV源碼,截圖加註釋到手機一份,要求作到脫稿說出流程 3.利用模版的繼承及CBV完成網站首頁 登錄 註冊頁面搭建 實現三者相互交互 選作題 1.嘗試着作一作圖書管理系統(將所學的知識點所有用進去) 無名有名+反向解析+模版的繼承 """