python_Django之模板模型
主要文件
manage.py ? ? ?創建服務器
settings.py????項目的配置信息
urls.py ? ? ? ? URL分發器(URLconf----URL和函數的映射表)
view.py ? ? ? ? 視圖(函數)
manage.py ?
啟動manage.py創建簡單的服務器,用于調測
python?manage.py?runserver?0.0.0.0:8000urls.py
patterns:第一個是空字符串(后面會解釋)
include:
?urls:
from?django.conf.urls.defaults?import?patterns,?include,?url from?mysite.views?import?hello??????#?通常是導*??views.?調用 urlpatterns?=?patterns('',url(r'^hello/$',?hello),)如果有人申請訪問/hello(尾部沒有斜杠/)會怎樣。 因為我們的URL模式要求尾部有一個斜杠(/),那個申請URL將不匹配。 然而,默認地,任何不匹配或尾部沒有斜杠(/)的申請URL,將被重定向至尾部包含斜杠的相同字眼的URL。 (這是受配置文件setting中APPEND_SLASH項控制的
?url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$',?views.article_detail),
?????? 這三個括號里的內容會以第二第三第四的參數傳給 函數,第一參是request
view.py
一個視圖就是Python的一個函數。這個函數第一個參數的類型是HttpRequest;它返回一個HttpResponse實例。
request?是一個觸發這個視圖、包含當前Web請求信息的對象,是類django.http.HttpRequest的一個實例。
from?django.http?import?HttpResponse def?hello(request):return?HttpResponse("Hello?world")????#?直接返回字符串 --------------------------------------------------------------------- from?django.shortcuts?import?render def?be_001(request):return?render(request,'001.html')????#?返回template文件下的001.htmlsettings.py
設置指定URLconf ?(url分發器)
ROOT_URLCONF?=?'mysite.urls'?????#?即mysite/urls.py進來的請求轉入/hello/.
Django通過在ROOT_URLCONF配置來決定根URLconf.
Django在URLconf中的所有URL模式中,查找第一個匹配/hello/的條目。
如果找到匹配,將調用相應的視圖函數,并把HttpRequest?對象作為第一個參數
視圖函數返回一個HttpResponse
Django轉換HttpResponse為一個適合的HTTP response, 以Web page顯示出來
指定模板路徑
TEMPLATE_DIRS?=?(os.path.join(os.path.dirname(__file__),?'templates').replace('\\','/'),#?自動獲取settings.py的路徑,并拼接得到模板路徑 ) #?單元素元組中必須使用逗號,以此消除與圓括號表達式之間的歧義。模板
在project目錄?(django-admin.py?startproject)中??輸入命令?python?manage.py?shell啟動交互界面(會自動加載相關配置)
循環判斷
{%?for?item?in?item_list?%}? ? ?#?表示當前循環的執行次數的整數計數器。 這個計數器是從1開始的,?forloop.counter0從零開始
<p>` forloop`.`counter `: ` item `</p> ? ?#?forloop.revcounter?是表示循環中剩余項的整型變量,forloop.revcounter0
{% endfor?%}????? #forloop.first?是一個布爾值,如果該迭代是第一次執行,那么它被置為true,forloop.last
?# ?forloop.parentloop?是一個指向當前循環的上一級循環的?forloop?對象的引用(在嵌套循環的情況下)????????????????????????????
{%?if?ordered_warranty?%}?????????# 只能用一種邏輯操作符 and 或 or ,兩個一起用不可以的
{% else %}
{% endif %}
{% ifequal user currentuser %} ? ? ?# 判斷 user currentuser 是否相等,字符串要“”,只能判斷兩個變量是否相等
? ?<h1>Welcome</h1> ? ? ? ? ? ? ? ?# 不能用于判斷變量是否等于什么,True {op:123} [1,2,3]等等
{% endifequal %}
變量賦值
{{?person_name?}} ??稱為?變量(variable)?。這意味著在此處插入指定變量的值。
>>>?from?django?import?template????????????????#?Template?可用render方法傳?Context?參數 >>>?t?=?template.Template('My?name?is?{{?name?}}.') >>>?c?=?template.Context({'name':?'Adrian'}) >>>?print?t.render(c) My?name?is?Adrian. >>>?c?=?template.Context({'name':?'Fred'}) >>>?print?t.render(c)????????????????????#?返回的是Unicode?r'' My?name?is?Fred.Django模板系統的基本規則:?寫模板,創建?Template?對象,創建?Context?, 調用?render()?方法。
>>>?from?django.template?import?Template,?Context >>>?import?datetime >>>?person?=?{'name':?'Sally',?'age':?'43'} >>>?t?=?Template('{{?person.name?}}?is?{{?person.age?}}?years?old.') >>>?c?=?Context({'person':?person}) >>>?t.render(c) u'Sally?is?43?years?old.' >>>?d?=?datetime.date(1993,?5,?2)????????#時間也可以這么用? >>>?d.year 1993 >>>?t?=?Template('Item?2?is?{{?items.2?}}.')????????????#?列表索引(不能用負數) >>>?c?=?Context({'items':?['apples',?'bananas',?'carrots']})#調用方法時并沒有使用圓括號?而且也無法給該方法傳遞參數; >>>?t?=?Template('{{?var?}}?--?{{?var.upper?}}?--?{{?var.isdigit?}}')????#?var變量,調用upper和isdigit方法 >>>?t.render(Context({'var':?'hello'})) u'hello?--?HELLO?--?False'
字典類型查找 (比如?foo["bar"]?)
屬性查找 (比如?foo.bar?)
方法調用 (比如?foo.bar()?)
列表類型索引查找 (比如?foo[bar]?)
?系統使用找到的第一個有效類型。 這是一種短路邏輯。
?一個變量不存在,模板系統會把它展示為空字符串,不做任何事情來表示失敗。
方法調用
拋異常
在方法查找過程中,如果某方法拋出一個異常的話它將被傳播(報錯)。
若該異常有一個?silent_variable_failure?屬性并且值為True?,模板里的指定變量會被置為空字符串(不報錯)
模版中避免關鍵函數的誤操作
def delete(self):
# Delete the account
delete.alters_data = True
# 把delete看成一個對象,設置它的alters_data屬性。這樣在渲染的時候,就會變成failed silent。不會執行
注釋
單行
多行
{%?comment?%} This?is?a multi-line?comment. {%?endcomment?%}過濾器
常用的幾個
模板過濾器是在變量被顯示前修改它的值的一個簡單方法。
addslashes?: 添加反斜杠到任何反斜杠、單引號或者雙引號前面。 這在處理包含JavaScript的文本時是非常有用的。
date?: 按指定的格式字符串參數格式化?date?或者?datetime?對象, 范例:
{{?pub_date|date:"F?j,?Y"?}}格式參數的定義在附錄F中。
length?: 返回變量的長度。 對于列表,這個參數將返回列表元素的個數。 對于字符串,這個參數將返回字符串中字符的個數。 你可以對列表或者字符串,或者任何知道怎么測定長度的Python 對象使用這個方法(也就是說,有?__len__()?方法的對象)
詳細 https://www.douban.com/note/145065606/
模板加載
settings.py
import?os.pathTEMPLATE_DIRS?=?(os.path.join(os.path.dirname(__file__),?'templates').replace('\\','/'), )
在視圖中
更為簡潔的視圖
from?django.shortcuts?import?render_to_response import?datetimedef?current_datetime(request):now?=?datetime.datetime.now()return?render_to_response('current_datetime.html',?{'current_date':?now})#?返回HttpResponse?對象;#?第一個參數必須是要使用的模板名稱;#?第二個參數,那么該參數必須是為該模板創建?Context?時所使用的字典,默認是空字典locals() 技巧
def?current_datetime(request):now?=?datetime.datetime.now()????????#?多余的變量名...return?render_to_response('current_datetime.html',?{'current_date':?now})def?current_datetime(request):???????current_date?=?datetime.datetime.now()????????#?這個變量名和模板中的一致return?render_to_response('current_datetime.html',?locals())#?locals()囊括了函數執行到該時間點時所定義的一切變量。get_template()-模板子目錄
t?=?get_template('dateapp/current_datetime.html')return?render_to_response('dateapp/current_datetime.html',?{'current_date':?now})include?模板標簽(笨笨的嵌套網頁)
{%?include?template_name?%}如果{%?include?%}標簽指定的模板沒找到,Django將會在下面兩個處理方法中選擇一個:
如果?DEBUG?設置為?True?,你將會在 Django 錯誤信息頁面看到?TemplateDoesNotExist?異常。
如果?DEBUG?設置為?False?,該標簽不會引發錯誤信息,在標簽位置不顯示任何東西。
模板繼承(更加優雅的策略)
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01//EN">????????#?base.html <html?lang="en">????????????????????????????????????? <head><title>{%?block?title?%}{%?endblock?%}</title> </head> <body><h1>My?helpful?timestamp?site</h1> </body> </html{%?extends?"base.html"?%}????????????????????????#?繼承模板,替換同名block即可{%?block?title?%}The?current?time{%?endblock?%}{%?block?content?%} <p>It?is?now?{{?current_date?}}.</p> {%?endblock?%}要點:
基礎模板中的?{%?block?%}?標簽越多越好。
子模板不必定義父模板中所有的代碼塊。
不允許在同一個模板中定義多個同名的?{%?block?%}?。
模型
為了提供方便的數據訪問API, Django需要以?某種方式?知道數據庫層內部信息,有兩種實現方式。?
第一種方式是用Python明確地定義數據模型
第二種方式是通過自省來自動偵測識別數據模型。
(自省(運行時自動識別數據庫)會導致過載和有數據完整性問題。)
笨方法數據庫查詢
from?django.shortcuts?import?render_to_response????????#?重復同樣的代碼 import?MySQLdb?????????????????????????????????????????#?綁定死了MySQL?def?book_list(request):db?=?MySQLdb.connect(user='me',?db='mydb',?passwd='secret',?host='localhost')cursor?=?db.cursor()cursor.execute('SELECT?name?FROM?books?ORDER?BY?name')names?=?[row[0]?for?row?in?cursor.fetchall()]db.close()return?render_to_response('book_list.html',?{'names':?names})
Django數據庫層
from?django.shortcuts?import?render_to_response????????#?由Django數據庫層來處理 from?mysite.books.models?import?Book???????????????????#?底層數據庫代碼更為優化,數據庫選擇更靈活???????????????? def?book_list(request):books?=?Book.objects.order_by('name')return?render_to_response('book_list.html',?{'books':?books})settings.py?中數據庫的設置
DATABASES?=?{'default':?{'ENGINE':?'django.db.backends.',?#?Add?'postgresql_psycopg2',?'mysql',?'sqlite3'?or?'oracle'.'NAME':?'',??????????????????????#?Or?path?to?database?file?if?using?sqlite3.'USER':?'',??????????????????????#?Not?used?with?sqlite3.'PASSWORD':?'',??????????????????#?Not?used?with?sqlite3.'HOST':?'',??????????????????????#?Set?to?empty?string?for?localhost.?Not?used?with?sqlite3.'PORT':?'',??????????????????????#?Set?to?empty?string?for?default.?Not?used?with?sqlite3.}}MVC 模式
控制器(controller)?---->>>? ?模型(model)?---->>>? ?視圖(view)
MTV
"?C 由框架自行處理(URLconf)" ??---->>>? ?模型(Model)---->>>?視圖(Views)---->>>?模板(Template)
APP
理一理project和app:一個project包含多個app,為app提供相關配置,但model必須在各自的app中
python?manage.py?startapp?books????#?創建APP
在models.py中描述數據庫
與下面的sql效果一樣
CREATE?TABLE?"books_publisher"?("id"?serial?NOT?NULL?PRIMARY?KEY,"name"?varchar(30)?NOT?NULL,"address"?varchar(50)?NOT?NULL,"city"?varchar(60)?NOT?NULL,"state_province"?varchar(30)?NOT?NULL,"country"?varchar(50)?NOT?NULL,"website"?varchar(200)?NOT?NULL );?settings.py?激活app
MIDDLEWARE_CLASSES?=?(????????????????????????????????????????#?注釋部分后續解釋#?'django.middleware.common.CommonMiddleware',#?'django.contrib.sessions.middleware.SessionMiddleware',#?'django.contrib.auth.middleware.AuthenticationMiddleware', )INSTALLED_APPS?=?(#?'django.contrib.auth',#?'django.contrib.contenttypes',#?'django.contrib.sessions',#?'django.contrib.sites','mysite.books',???????????????????????? )
檢查上面模型的語法和邏輯(正常返 0 erros found)
python?manage.py?validate生成?CREATE?TABLE?語句
python?manage.py?sqlall?books提交到數據庫客戶端執行
python?manage.py?syncdb????????#?此命令不能用做修改刪除基本數據訪問
python?manage.py?shell
>>>?from?books.models?import?Publisher????????????#?導入Publisher模型類,與數據表進行交互 >>>?p1?=?Publisher(name='Apress',?address='2855?Telegraph?Avenue', ...?????city='Berkeley',?state_province='CA',?country='U.S.A.', ...?????website='http://www.apress.com/') >>>?p1.save() >>>?p2?=?Publisher(name="O'Reilly",?address='10?Fawcett?St.', ...?????city='Cambridge',?state_province='MA',?country='U.S.A.', ...?????website='http://www.oreilly.com/') >>>?p2.save() >>>?publisher_list?=?Publisher.objects.all() >>>?publisher_list [<Publisher:?Publisher?object>,?<Publisher:?Publisher?object>]下面不需要save,直接完成對象的創建與存儲至數據庫
>>>?p1?=?Publisher.objects.create(name='Apress', ...?????address='2855?Telegraph?Avenue', ...?????city='Berkeley',?state_province='CA',?country='U.S.A.', ...?????website='http://www.apress.com/')重寫__unicode__,方便
class?Author(models.Model):**def?__unicode__(self):**????????#?__unicode__()?方法可以進行任何處理來返回對一個對象的字符串表示**return?u'%s?%s'?%?(self.first_name,?self.last_name)**????#?必須返回Unicode,數字什么的會報錯插入更新
>>>?p?=?Publisher(name='Apress', ...?????????address='2855?Telegraph?Ave.', ...?????????city='Berkeley', ...?????????state_province='CA', ...?????????country='U.S.A.', ...?????????website='http://www.apress.com/')>>>?p.save()????????#相當于執行INSERT?INTO?books_publisher***??會把主鍵賦值給實例對象?p>>>?p.id 52????#?this?will?differ?based?on?your?own?data>>>?p.name?=?'Apress?Publishing'????????#?根據這個對象可更新數據 >>>?p.save()????????????????????????????#?并不是只更新修改過的那個字段,所有的字段都會被更新。#?部分更新后面再說查詢
>>>?Publisher.objects.all() [<Publisher:?Apress>,?<Publisher:?O'Reilly>]數據過濾(filter--返回列表)
>>>?Publisher.objects.filter(country="U.S.A.",?state_province="CA") [<Publisher:?Apress>]多個參數會被轉換成?AND?SQL從句,?因此上面的代碼可以轉化成這樣: SELECT?id,?name,?address,?city,?state_province,?country,?website FROM?books_publisher?? WHERE?country?=?'U.S.A.' AND?state_province?=?'CA';>>>?Publisher.objects.filter(name__contains="press")????#?在?name?和?contains?之間有雙下劃線 [<Publisher:?Apress>]???????????????????????????????????#?這里,contains部分會被Django翻譯成LIKE語句:注意,SQL缺省的?=?操作符是精確匹配的,?其他類型的查找也可以使用 WHERE?name?LIKE?'%press%';獲取單個對象
>>>?Publisher.objects.get(name="Apress") <Publisher:?Apress>MultipleObjectsReturned??#?結果是多個對象,拋出異常 DoesNotExist???#??DoesNotExist?異常?是?Publisher?這個?model?類的一個屬性,即?Publisher.DoesNotExist。在你的應用中,你可以捕獲并處理這個異常數據排序
>>>?Publisher.objects.order_by("-state_province",?"address")[<Publisher:?Apress>,?<Publisher:?O'Reilly>]#?減號?-?前綴逆向排序,第二個字段會在第一個字段的值相同的情況下被使用到class?Publisher(models.Model):**class?Meta:****ordering?=?['name']**#?在模型類(需要設置默認排序的)中,設置默認的排序方式,上述當你使用?Django?的數據庫?API?去檢索時,#?Publisher對象的相關返回值默認地都會按?name?字段排序連鎖查詢
>>>?Publisher.objects.filter(country="U.S.A.").order_by("-name") [<Publisher:?O'Reilly>,?<Publisher:?Apress>] #?即為SQL查詢?WHERE?和?ORDER?BY?的組合限制返回數據
更新
>>>?p?=?Publisher.objects.get(name='Apress') >>>?p.name?=?'Apress?Publishing' >>>?p.save()????????????????????#?這樣操作會更新所有的列(不僅僅是name列的值)指定更新
>>>?Publisher.objects.filter(id=52).update(name='Apress?Publishing')????#?id=52的表的name字段>>>?Publisher.objects.all().update(country='USA')????????#?所有Publisher的country字段值 2????????????#?update()方法會返回一個整型數值,表示受影響的記錄條數。刪除對象
>>>?p?=?Publisher.objects.get(name="O'Reilly")????#?刪除指定記錄 >>>?p.delete()>>>?Publisher.objects.filter(country='USA').delete()????#?同時刪除多條記錄 >>>?Publisher.objects.all().delete()多對多用兩個循環獲取 .all 獲取所有(列表) ?.first 獲取首個
轉載于:https://blog.51cto.com/woodcutter/1829390
總結
以上是生活随笔為你收集整理的python_Django之模板模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MapReduce程序的运行全貌
- 下一篇: 【Qt笔记】对象模型