一.Django的路由層(URLconf) 1.簡單的路由配置 urlpatterns = [ url(r'^admin/$', admin.site.urls), # 在urls中用正則捕獲待匹配的路徑,直行第二項的視圖函數,並在app01中的views中添加視圖函數 # def index(request): # return HttpResponse("ok") url(r'^index/$',views.index), ] 2.無名分組 (1)獲取年份 # 若要從URL 中捕獲一個值,只須要在它周圍放置一對圓括號。 url(r'^year/(\d{4})/$',views.year),#year_archive(request,2006) def year(request,year): date=datetime.datetime.now() return HttpResponse('year:%s' % (year)) (2)獲取年月 url(r'^year/(\d{4})/(\d{2})/$',views.year_month),#year_month(request,2006,12) def year_month(request,year,mouth): date = datetime.datetime.now() return HttpResponse('year:%s mouth:%s' % (year,mouth)) 注: 不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles。 每一個正則表達式前面的'r' 是可選的可是建議加上。它告訴Python 這個字符串是「原始的」 —— 字符串中任何字符都不該該轉義 3.有名分組 獲取年月 url(r'^year/(?P<year>\d{4})/(?P<mouth>\d{2})/$',views.year_month),#year_month(request,year=2006,mouth=12) def year_month(request,year,mouth): date = datetime.datetime.now() return HttpResponse('year:%s mouth:%s' % (year,mouth)) 給正則表達式中的每個括號起一個名字,視圖函數在使用時, 只能使用該名字,視圖函數的參數由位置參數變成了關鍵字參數 4.分發 項目的url中 url(r'^app01/',include('app01.urls')), url(r'^app02/',include('app02.urls')), 注: 此時不要忘了引入include from django.conf.urls import include app01中 from django.conf.urls import url,include from app01 import views urlpatterns=[ url(r'^aaa/$',views.aaa), url(r'^bbb/$',views.bbb), ] app02中 from django.conf.urls import url,include from app02 import views urlpatterns=[ url(r'^ccc/$',views.ccc), url(r'^ddd/$',views.ddd), ] app01的views中 def aaa(request): return HttpResponse('aaa') def bbb(request): return HttpResponse('bbb') app02的views中 def ccc(request): return HttpResponse('ccc') def ddd(request): return HttpResponse('ddd') 5.反向解析 當程序進入aaa分支 urlpatterns=[ url(r'^aaa/$',views.aaa), url(r'^bbb/$',views.bbb,name='xxx'), ] 進入aaa的視圖函數 def aaa(request): return render(request,'aaa.html') 獲取aaa.html頁面 表單提交到別名爲xxx的地址中,返回上上層中,找到別名爲xxx的地址,並進入 <form action="{% url 'xxx' %}"> <input type="text" name="content"> <input type="submit"> </form> 進入bbb視圖函數 def bbb(request): return HttpResponse('bbb') 注:反向解析的做用是,若是項目完成後,須要修改某個地址,只須要修改最初的一出,不用大量修改二.Django的視圖層 視圖層:請求對象(request)和響應對象(HttpResponse) 1.request屬性 def index(request): print(request.method) #請求方式 GET print(request.path) #請求路徑 /index/ print(request.POST) #post請求的數據 字典格式 <QueryDict: {}> print(request.GET) #get請求的數據 字典格式 <QueryDict: {}> print(request.META) #請求頭 ... print(request.get_full_path()) #返回 path,若是能夠將加上查詢字符串。/index/ print(request.is_ajax()) #若是請求是經過XMLHttpRequest 發起的,則返回True, False return HttpResponse('ok') 2.HttpResponse對象 (1)HttpResponse() 括號中能夠是一個普通字符串,也能夠是一個標籤字符串 (2)render() a.讀取文件字符串 b.嵌入變量 在要執行的視圖函數中動態改變變量 def index(request): apple = '蘋果' return render(request,'start.html',{'apple':apple}) 在對應的HTML文件中動態渲染變量 <body> <p>{{ apple }}</p> </body> (3)redirect()重定向 在瀏覽器進入此地址時,讓瀏覽器從新發一個請求,請求的地址時redirect返回的地址 def cdx(request): return redirect('/index/')三.Django的模板層 1.渲染變量{{ }} (1)深度查詢 當調用視圖函數中的index方法時 def index(request): import datetime name='shy' age=20 hobby=['eat','drink'] date=datetime.datetime.now() class Foo(): def __init__(self,name,age): self.name=name self.age=age # 此時的方法只能是無參的方法 def run(self): return 'running' a1=Foo('aaa',1) a2=Foo('bbb',2) a3=Foo('ccc',3) list=[a1,a2,a3] # locals()可代替傳全部參數 return render(request,'index.html',{'name':name,'age':age,'hobby':hobby,'date':date,'list':list}) 被盜調用的index.HTML <body> <p>{{ name }}</p> <p>{{ age }}</p> <p>{{ hobby.1}}</p> <p>{{ date }}</p> <p>{{ list.0.name }}</p> <p>{{ list.0.run }}</p> </body> (2)過濾器 date:日期過濾器 語法:{{ var|過濾器名字:參數 }} <p>{{ date|date:'Y:m:d' }}</p> 做用:能夠將日期轉換成想要的格式 default:若是一個變量是false或者爲空,使用給定的默認值。不然,使用變量的值 語法:{{ value|default:'默認值'}} <p>{{ list|default:'沒有符合條件的書籍' }}</p> length:返回值的長度。它對字符串和列表都起做用 語法:{{ value|length }} filesizeformat:將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。 語法:{{ value|filesizeformat }} slice:切割字符串 語法:{{ value|slice:'1;3' }} truncatechars:若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾 語法:{{ value|truncatechars:9 }} 注:在給定的數目-3處階段,留三個位置給... truncatewords :若是字符串字符多於指定的單詞數量,那麼會被截斷 語法:{{ value|truncatewords:9 }} safe Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。 可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統, 後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本, 若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有兩種方式, 若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。好比: value="<a href="">點擊</a>" {{ value|safe}} 2.渲染標籤{% %} for 標籤 {% for foo in list %} <p>{{ foo.age }}</p> {% endfor %} 注:不能像python同樣break forloop輔助功能 forloop.counter 序號從1開始 forloop.counter0 序號從0開始 forloop.revcounter 序號倒序,最後一個是1 forloop.revcounter0 序號倒序,最後一個是0 forloop.first 判斷是否是第一個 forloop.last 判斷是否是最後一個 if標籤 {% if age > 18 %} <p>100</p> {% elif age <= 18 %} <p>{{ age }}</p> {% endif %} 注:判斷的符號兩邊要有空格 with標籤(至關於起了一個簡短的名字,在小區域內能夠使用別名) {% with list.0.name as a %} <p>{{ a }}</p> {% endwith %} csrf_token 在form表單中的任意一個位置加一個{{ csrf_token }}便可解決form表單提交時的forbition 其實是偷偷加了一個 <input type='hidden' name='scrfmiddlewaretoken' value='hhasgd7ew43jerf8efu'> 作了一個通行證,用於攔截不經過get請求就發post請求的人 3.模板繼承 (extend) 在視圖函數中 def index(request): return render(request,"index.html") def order(request): order_list=["訂單1","訂單2","訂單3"] return render(request,"order.html",{"order_list":order_list}) def shopping_list(request): shopping_list=["蘋果","香蕉","蘋果"] return render(request,"shopping_list.html",{"shopping_list":shopping_list}) 在母版中 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> {# block標籤標示:子模版可能會覆蓋掉模版中的這些位置。#} {% block title %} <title>Title</title> {% endblock %} <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <style> *{ margin: 0; padding: 0; } .header{ width: 100%; height: 50px; } </style> </head> <body> <div class="header"></div> <div class="container"> <div class="row"> <div class="col-md-3"> {% block menu %} <div class="panel panel-success"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> <p><a href="/index/">首頁</a></p> <p><a href="/order/">訂單</a></p> <p> <a href="/shopping_list/">商品列表</a></p> </div> </div> {% endblock %} </div> <div class="col-md-9"> {% block content %} <h3>welcome!</h3> {% endblock content%} </div> </div> </div> </body> </html> 在index頁面中 {#表示繼承的模板,必定要寫在如下內容的前面,不然會出錯#} {% extends "base.html" %} {% block content %} super的意思是既顯示母版的內容,又顯示這個內容 {{ block.super }} <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 title %} <title>首頁</title> {% endblock %} 在order頁面中 {% extends "base.html" %} {% block content %} <h3>訂單列表</h3> {% for order in order_list %} <p>{{ order }}</p> {% endfor %} {% endblock %} {% block title %} <title>訂單</title> {% endblock %} 在shopping_list頁面中 {% extends "base.html" %} 每一個模板都有本身的題目,因此順序能夠打亂 {% block title %} <title>商品列表</title> {% endblock %} {% block content %} <h3>商品列表</h3> {% for foo in shopping_list %} <p>{{ foo }}</p> {% endfor %} {% endblock %}