1、Django請求生命週期
1.路由層urls.pycss
1.1 urls.py配置基本格式前端
from django.conf.urls import url urlpatterns = [ url(正則表達式, views視圖函數,參數,別名), ]
1.11.x版本默認python
from django.conf.urls import url urlpatterns = [ url(r'^admin/', admin.site.urls),
url(r'^test/$', views.test),
]
# 獲取到用戶輸入的url後,根據正則匹配是否對應
# http://127.0.0.1:8000/test 請求的時候實際是請求了2次,第一次請求是按照瀏覽器輸入的進行請求,可是沒有匹配到,第二次請求瀏覽器會自動在末尾加一個/以後進行匹配,若是還匹配不上直接報錯
# 注意事項 1 urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則再也不繼續。 2 若要從URL中捕獲一個值,只須要在它周圍放置一對圓括號(分組匹配)。 3 不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles。 4 每一個正則表達式前面的'r' 是可選的可是建議加上。
urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'test/[0-9]{4}/$', views.test), # 無名分組:會將分組內的結果 當作位置參數自動傳遞給後面的視圖函數views.py url(r'test/([0-9]{4})/$', views.test), # url(r'^test/(\d+)/$',views.test), # 有名分組:會將分組內的結果 當作關鍵字參數自動傳遞給後面的視圖函數 url(r'^testadd/(?P<id>[0-9]{4})/$',views.testadd), ] # 無名分組:http://127.0.0.1:8000/test/3333/,視圖函數加參數後能夠訪問,若是不加會提示test() takes 1 positional argument but 2 were given # 有名分組
1.2 反向解析jquery
根據別名動態解析出能夠匹配上視圖函數以前的url的一個結果(注意:在起別名的時候,必定要保證 全部的別名都不能重複,必須是惟一的)正則表達式
# urls.py url(r'^testxxx/',views.test,name='t') url(r'^test/(\d+)/$',views.test,name='ttt'), # 前端 沒有正則表達式的反向解析 {% url 't' %} 無名分組反向解析 有名分組同上
有正則表達式的反向解析
{% url 'ttt' 1 %} # 數字一般是數據庫中字典的pk值 # 後端 from django.shortcuts import render,HttpResponse,redirect,reverse 沒有正則表達式的反向解析 reverse('t')
無名分組反向解析 reverse('ttt',args=(1,)) #有正則表達式的反向解析函數視圖views.py 有名分組同上 # urls.py中使用別名後,testxxx不管怎麼變,瀏覽器中路徑也會自動變化,動態解析到前端
有名分組和無名分組可否混合使用?
---有名無名不能混合使用!!!數據庫
1.3 頁面僞靜態django
# 僞靜態 讓一個動態頁面假裝成一個看似數據已經寫死了的靜態頁面,實際上是通過了視圖函數處理,動態渲染的頁面 好處:讓搜索引擎加大對你這個頁面的收藏力度,當別人搜索你這個頁面相關內容,提升優先展現機率(花錢最好) 加大seo查詢
# 例如:在urls.py中將路由設置成,視圖函數views.py中仍是不變:return HttpResponse("index.html")
url(r'^index.html$',views.index),
例如:10982293.html https://www.cnblogs.com/Dominic-Ji/articles/10982293.html
1.4 django版本區別1.x與2.xjson
1.X 路由裏面用的是url() 2.X 路由裏面的用的是path() url第一個參數放的是正則表達式 而你的path第一個參數寫什麼就是什麼,不支持正則 若是你還想使用第一個參數是正則的方法 django2.X版本中有一個叫re_path() ps:2.x中re_path就等價於1.x中的url # 雖然path不支持正則表達式,可是它提供了五種轉換器(瞭解)
1.5 路由分發bootstrap
當一個django項目下面有多個app的狀況下,總的urls.py中路由與視圖函數的對應關係太多 不便於管理
這個時候就能夠再每一個app下建立本身的urls.py,總的urls.py再也不作對應關係,而只是作分發任務 每一個app下均可以有本身的urls.py static文件夾 templates模板文件,也就意味着 每一個app均可以被獨立的開發出來 而不須要討論交互
# 路由分發:根據前綴,去對應的目錄下查找路由 # 總路由下urls.py配置 # 重名的使用別名 from django.conf.urls import url,include from app01 import urls as app01_urls from app02 import urls as app02_urls urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/',include(app01_urls)), url(r'^app02/',include(app02_urls)), ] # 應用app01下的路由 from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^urlindex',views.urlindex), ] # app01下的視圖函數views.py from django.shortcuts import render,HttpResponse,redirect def urlindex(request): return HttpResponse("app01下的index") # 應用app02下的路由 from app02 import views urlpatterns = [ url(r'^urlindex',views.urlindex) ] # app02下的視圖函數views.py from django.shortcuts import render,HttpResponse,redirect def urlindex(request): return HttpResponse("app02下的urlindex") # 訪問app01下的連接:http://127.0.0.1:8000/app01/urlindex # 訪問app02下的連接:http://127.0.0.1:8000/app02/urlindex # 均可以顯示對應的提示
# 若是2個app下起了相同的名字,那麼反向解析不支持自動查找應用前綴,須要瞭解名稱空間的概念 # app01 urlpatterns = [ url(r'^urlindex',views.urlindex,name='aaa') ] # app02 urlpatterns = [ url(r'^urlindex',views.urlindex,name='aaa') ] # views.py中都打印下print('aaa') # 訪問app01和app02的urlindex後端打印的都是同樣的 # 第一種方法: # 反向解析的時候能夠在name='aaa'中添加前綴解決 # 例如:name='app01_aaa' # 第二種方法: # 名稱空間(瞭解既可):在分發的時候再起一個名字 # 總路由urls.py中 urlpatterns = [ url(r'^app01/',include(app01_urls,namespace='app01')), url(r'^app02/',include(app02_urls,namespace='app02')), ] #app01中的路由urls.py urlpatterns = [ url(r'^urlindex',views.urlindex,name='aaa') ] # app01的views.py def urlindex(request): print(reverse('app01:aaa')) return HttpResponse("app01下的index") # app02的路由 urlpatterns = [ url(r'^urlindex',views.urlindex,name='aaa') ] # app02的views.py def urlindex(request): print(reverse('app02:aaa')) return HttpResponse("app02下的urlindex") # 而後分別訪問就正常了
# 使用importlib方法:
2. 視圖層
2.1 JsonResponse
# views.py import json def index(request): d = {'name':'simon','password':'123','hobby':'讀書'} # 前端不支持字典,須要轉成json格式 return HttpResponse(json.dumps(d,ensure_ascii=False)) # 前端頁面顯示:http://127.0.0.1:8000/index/ {"name": "simon", "password": "123", "hobby": "讀書"} # 第二種方式: from django.http import JsonResponse def index(request): d = {'name':'simon','password':'123','hobby':'讀書'} # 前端不支持字典,須要轉成json格式 # return HttpResponse(json.dumps(d)) return JsonResponse(d) # JsonResponse直接轉換成json格式 # 前端沒顯示中文,能夠經過JsonResponse源代碼來看方法 # return JsonResponse(d,json_dumps_params={'ensure_ascii':False})
2.2 FBV與CBV
FBV function based views
CBV class based views
# views.py from django.views import View class MyLogin(View): def get(self,request): return HttpResponse("Get") def post(self,request): return HttpResponse("Post") # urls.py中如何添加路徑? # CBV路由配置 url(r'^login/',views.MyLogin.as_view()), # 能夠在前端home.html寫一個頁面測試post提交方式 <form action="/login/" method="post"> <input type="submit"> </form> # 能夠看到咱們訪問login直接返回Get # 訪問home.html點擊提交就會跳到login頁面顯示post
# 能夠看到get請求來走get,post請求走post
3.模板層
模板語法--模板傳值
# 模板語法 url.py url(r'^demo/',views.demo), # views.py def demo(request): i = 1 f = 1.11 s = 'hello' # s = [] l = [1,2,3,4,5,6,7,8,9] t = (1,2,3,4) d = {'name':'simon','password':'123'} se = {1,2,3,4} # 經過字典傳值方式 # return render(request,'demo.html',{'xxx':[1,2,3,4]}) def foo(): print("foo") return "0000000oooooooooo" class Demo(object): def index(self): return 'index' @classmethod def login(cls): return 'cls' @staticmethod def reg(): return 'reg' obj = Demo() return render(request,'demo.html',locals()) # locals 會將所在名稱空間中的全部名字所有傳遞給前端頁面 # 前端頁面 # 第一種傳值方式 return render(request,'demo.html',{'xxx':[1,2,3,4]}) # 前端使用 {{ xxx }} # 第二種傳值方式 # locals 會將所在名稱空間中的全部名字所有傳遞給前端頁面 return render(request,'demo.html',locals()) # 前端頁面須要將全部定義的:i f s等使用雙大括號括起來顯示 # 若是是函數傳到前端顯示 <p>{{ foo }} 若是是函數名,傳遞到前端會自動加()調用,將調用後的結果展現到前端頁面</p> #若是是類 {#<p>{{ obj.index }} 只要是方法 都會自動加括號調用</p>#}
# 獲取列表字典中某一個值
前端{{ l.0 }} or {{ d.name }}
3.1.過濾器
# 後端3中demo類中直接定義n和i import datetime ctime = datetime.datetime.now() sss = 'sadfasf sdfasf fasdfsadf sdfa' # 前端: {{i|add:19}} # 結果:20 {{n|filesizeformat}} # n的值進行轉化成文件大小M、G等 {{ ctime|date:'Y-m-d' }} # 日期獲取 {{ sss|truncatechars:20 }} # 截斷一部分...來省略(20包含3個點) {{ sss|truncatewords:2 }} # 截斷,只識別空格
#後端 def demo(request): h = "<h1>我是h1標籤</h1>" s1 = "<script>alter(123)</script>" # 後端轉義views.py from django.utils.safestring import mark_safe s2 = "<h2>我是h2標籤</h2>" s2 = mark_safe(s2) # 這樣前端就不須要用safe了 # safe告訴前端我這個代碼是安全的,能夠渲染 # 前端轉義 {{ h|safe }} {{ s1 }} # 這個若是加safe,前端就會死循環 {{ s2 }}
3.2 標籤
# 後端 def demo(request): l = [1,2,3,4,5,6,7,8,9] s3 = [1,2] s4 =[None,1] # 模板語法的if判斷 # 前端demo.html {% if s3 %} <p> 有值{{ s3 }}</p> # 返回結果就是這個了 {% else %} <p>這個東西是空的</p> {% endif %} {% if s4.0 %} <p> 有值{{ s4 }}</p> {% elif s4.1 %} <p>沒值</p> {% else %} <p>這個東西是空的</p> {% endif %} # 就算值取不到也不會報錯 {% for foo in l %} {# # foo爲每次列表循環的元素,first爲第一個值,last爲最後一個值,中間能夠#} {% if forloop.first %} <p>first...</p> {% elif forloop.last %} <p>這是last</p> {% else %} <p>繼續啊~~~</p> {% endif %} {% empty %} <p>是空的,不能循環</p> {% endfor %}
3.3 模板的繼承與導入
# 模板的繼承 # 在你想作成模板的頁面上 添加block塊兒 來標識其餘用戶能夠佔用的區域 {% extends 'tmp.html' %} {% block content %} <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 %} # 先在模板中劃定區域,以後子板利用block就可以找到模板中能夠被使用的區域 # 一般狀況下 模板中最少有三個區域 css content js ps:模板中的block塊兒越多 頁面的可擴展性越高
# 模板的導入 將一塊html頁面做爲模塊的方式 導入使用 {% include 'goodpage.html' %} 將goodpage.html頁面內容直接導入到該語句的位置
# 模板的繼承與導入 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script> <link href="/static/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-default"> <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="/loginn/" class="list-group-item active">登陸</a> <a href="/register/" class="list-group-item">註冊</a> <a href="#" class="list-group-item">Morbi leo risus</a> <a href="#" class="list-group-item">Porta ac consectetur ac</a> <a href="#" class="list-group-item">Vestibulum at eros</a> </div> </div> <div class="col-md-9"> {% block content %} <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> </body> </html> # login.html 模板的導入 {% extends 'tmp.html' %} {% block content %} <h3>登陸</h3> <form action="" method="post" class="form-group"> <p>username:<input type="text" class="form-control"></p> <p>password:<input type="text" class="form-control"></p> <input type="submit" class="btn btn-danger pull-right"> </form> {% endblock %} # reg.html模板的導入與繼承 {% extends 'tmp.html' %} {% block content %} {# 模板的導入#} {% include 'good.html' %} <h3 class="text-center">註冊</h3> <form action="" method="post" class="form-group"> <p>username:<input type="text" class="form-control"></p> <p>password:<input type="text" class="form-control"></p> <input type="submit" class="btn btn-danger pull-right"> </form> {% endblock %}