Django Python實戰
Django提供了一個高級的框架,用它只需要很少的幾行代碼就能完成一個Web應用。
Django中容易犯的和元組相關的錯誤:
>>> b = ("just-one")
>>> b[0]
'j'
>>> d = "just-one",
>>> d[0]
'just-one'
元組是由逗號決定的,而不是小括號。
裝飾器
Python的裝飾器指的是一種讓你能改變或者說“裝飾”函數行爲的機制,它能讓函數執行一些和原本設計不同,或時在原有基礎上額外的操作。裝飾器也可以說是對函數的一個包裝。這些額外的任務包括寫日誌、計時、過濾等。
@deco
def foo():
pass
在這個例子裏,deco就是一個裝飾了foo函數的裝飾器函數(decorator function)。它先把foo函數拿過來,加上一些額外功能後再重新賦值給foo。@deco的語法和下面的代碼是等價的。
foo = deco(foo)
一個簡單的例子:
def log(func):
def wrappedFunc():
print "*** %s() called" % func.__name__
return func()
return wrappedFunc
@log
def foo():
print "inside foo()"
執行代碼後所生成的結果:
>>> foo()
*** foo() called
inside foo()
Django速成:構建一個Blog
創建項目
項目是一個包含了組成單個網站的所有文件的目錄。
Django提供了一個叫django-admin.py的命令來幫助創建一個項目的目錄。
爲blog項目創建一個項目目錄的django-admin.py命令是:
django-admin.py startproject mysite
生成的目錄中:
- manage.py 工具
- settings.py 包含了項目的默認設置,包括數據庫信息、調試標誌以及其他一些重要的變量。
- urls.py 在Django裏叫URLconf,它是一個將URL模式映射到你應用程序上的配置文件。
startproject命令創建的所有文件都是Python的源代碼文件。這裏沒有XML、.ini文件,或是任何時髦的配置語法。Django追求的是儘可能地保持“純Python”這一理念。
運行開發服務器
Django內置了一個Web服務器,它不是用來部署公共站點的,而是用來快速開發,優點如下:
- 不需要安裝Apache等服務器軟件
- 會自動檢到你對Python源代碼的修改並且重新加載那些模塊,無需每次修改代碼後都手動重啓Web服務器
- 知道如果爲admin應用程序尋找並顯示靜態的媒體文件,所以你就可以直接使用它
啓動服務器:
./manage.py runserver
創建Blog應用
有了項目之後就可以在它下面創建應用,按Django的說法是app。
創建blog app:
./manage.py startapp blog
要告訴Django這個app是項目裏的一部分,需要編輯settings.py文件(配置文件)。
在settings.py文件尾部找到INSTALLED_APPS元組。把app以模塊的形式添加到元組中(注意結尾的逗號):
'mysite.blog'
設計你的Model
在models.py文件中加入以下代碼:
class BlogPost(models.Model):
title = models.CharField(max_length=150)
body = models.TextField()
timestamp = models.DateTimeField()
每個變量都和普通的類屬性一樣被定義爲一個特定變量類(field class)的實例。這些變量類也是在django.models裏定義,它們的種類非常多,從BooleanField到XMLField應有盡有。
設置數據庫
在settings.py文件中設置數據庫引擎、用戶名、密碼等信息,書中寫的是設置DATABASE_ENGINE
、DATABASE_NAME
等變量,比如:
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = r'C:\py\django\db\django.db'
不過最新版本的Django貌似是使用以下方式:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
創建表
執行以下命令後Django會在指定數據庫中創建某些表:
./manage.py syncdb
*** 本人興高采烈地裝上最新版的Django,實踐發現和書中的不完全一樣,比如syncdb已經不支持了,而是改成了migrate,所以這本書的筆記還是隻記錄基本原理吧,詳細步驟就不記錄了 ***
在models.py中定義的BlogPost模型類實際上相當於定義了一個表,而成員變量則是一個個字段,執行上述命令後,Django將在數據庫中自動根據models.py中的定義創建一系列表。
當然在settings.py中列出的app才能自動創建出表。
admin應用
通過添加admin應用,可以通過 http://127.0.0.1:8000/admin 頁面來管理註冊到admin應用的模型,可以往模型(數據庫表)中添加記錄,相當於一個數據庫管理頁面。
在settings.py文件中INSTALLED_APPS元組中添加'django.contrib.admin',
。
每次添加完應用都要執行更新數據庫表的命令。
接下來是在admin應用中註冊模型,blog/models.py中:
from django.db import models
from django.contrib import admin
class BlogPost(models.Model):
title = models.CharField(max_length=150)
body = models.TextField()
timestamp = models.DateTimeField()
admin.site.register(BlogPost)
建立Blog的公共部分
從Django的角度來說,一個頁面具有三個典型的組件:
- 一個模板(template),模板負責將傳遞進來的信息顯示出來(用一種類似Python字典的對象Context)
- 一個視圖(view)函數,它負責獲取要顯示的信息,通常都是從數據庫裏取得
- 一個URL模式,它用來把收到的請求和你的視圖函數匹配,有時也會向視圖傳遞一些參數
創建模板
模板就是一個html文件,其中可以使用特殊的變量標籤,用來獲得傳入的數據,也可以使用for循環等,可以將模板標籤理解爲Django定義的一種特殊的語法,就像嵌在HTML文檔中的PHP腳本一樣。
<h2>{{ post.title }}</h2>
<p>{{ post.timestamp }}</p>
<p>{{ post.body }}</p>
假設傳給模板一個名爲post的BlogPost模型對象,以上的模板代碼分別從BlogPost對象的titile、timestamp、body變量裏獲取了相應的值。
使用for模板標籤顯示多篇blog帖子:
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.timestamp }}</p>
<p>{{ post.body }}</p>
{% endfor %}
將以上模板代碼保存到blog app目錄裏的templates目錄下。
創建視圖
想在編寫一個從數據庫讀取所有blog帖子的視圖函數,並用我們的模板將它們顯示出來。
打開blog/views.py然後輸入:
from django.template import loader, Context
from django.http import HttpResponse
from mysite.blog.models import BlogPost
def archive(request):
posts = BlogPost.objects.all()
t = loader.get_template("archive.html")
c = Context({ 'posts' : posts })
return HttpResponse(t.render(c))
每個Django視圖函數都將django.http.HttpRequest對象作爲它的第一個參數。
創建一個URL模式
我們的頁面還差一步就可以工作了,還需要一個URL。
第一步:
在mysite/urls.py中添加url(r'^blog/', include('mysite.blog.urls'))
,此句是把blog開頭的URL轉到blog目錄下的urls.py處理
第二步:
在blog/urls.py中添加:
from django.conf.urls.defaults import *
from mysite.blog.views import archive
urlpatterns = patterns('', url(r'^$'), archive)
以上代碼是對URL使用archive視圖函數進行顯示。
小總結:
Django的大體流程如下:瀏覽器中輸入URL,URL將由urls.py進行路由,交由指定的views.py中的視圖函數進行顯示,視圖函數通過models.py從數據庫中獲得數數據然後將數據傳入模板文件(包含模板標籤的HTML文件),經過處理後,最終的HTML文件被髮送到瀏覽器客戶端。
最後的潤色
模板繼承
可能多個頁面會基於同一個基礎風格,首先創建一個base.html,其中包含以下模板便籤:
{% block content %}
{% endblock %}
然後可以定義一個子模板繼承該基礎模板:
{% extends "base.html" %}
{% block content %}
...
{% endblock %}
該子模板表示繼承base.html,並且將子模板中的content命名塊中的所有內容填入到base.html中相應的塊中。
按時間排序
設置model的默認排序方法是給它定義一個Meta嵌套類:
class Meta:
ordering = ('-timestamp',)
如果省略掉開頭的’-’,則按升序排列。
使用模板過濾器格式化時間戳
<p>{{ post.timestamp|date }}</p>
使用一個管道符號,就可以把過濾器應用到變量之上了。date是一個過濾器。
起始
動態網站基礎
基本流程:用戶向Web服務器請求一個文檔,Web服務器隨即獲取或生成這個文檔,服務器再把結果返回給用戶的瀏覽器,最後瀏覽器將這個文檔渲染出來。
Django將請求和響應表示成相對簡單的Python對象,用屬性來表示其數據,以及用方法來進行更復雜的操作。
SQL是用來定義和查詢數據庫的語言,通常被進一步抽象爲一個ORM(對象關係映射),它可以把數據庫裏的數據映射爲面嚮對象語言裏的代碼對象。
理解模型、視圖和模板
- 模型: 控制數據
- 視圖: 定義顯示的方法
- 控制器: 在兩者之間斡旋,並且讓用戶可以請求和操作數據
多個控制器可以根據用戶的不同對同一個數據模型做出不同程度的訪問,或是允許通過GUI應用以及email或是命令行來提交數據。
Django的核心理念
- Django希望儘量Pythonic一點
- 不要重複自己(DRY)
- 松耦合與靈活性
- 快速開發