1、安裝配置html
一、下載地址:python
https://www.djangoproject.com/download/mysql
二、安裝:linux
tar zxvf Django-1.6.1.tar.gz && cd Django-1.6.1 && python setup.py install
三、學習URL:web
https://docs.djangoproject.com/en/1.6/正則表達式
http://djangobook.py3k.cn/2.0/sql
http://django-chinese-docs.readthedocs.org/en/latest/shell
http://man.chinaunix.net/develop/python/mod_python/mod_python.html數據庫
http://www.cnblogs.com/holbrook/archive/2012/03/02/2357343.html#2779364apache
http://www.douban.com/group/django/
http://www.cnblogs.com/BeginMan/category/458761.html
http://www.cnblogs.com/holbrook/tag/django/default.html?page=2
過濾器:http://blog.csdn.net/chuncaijiayou/article/details/15026931
2、入門
一、新建項目:
可使用 django-admin.py 腳原本建立項目,該腳本還有更多功能,可使用 django-admin.py help 來查看,如也可直接建一個應用: django-admin.py startapp appname。(也可使用 manage.py 完成一樣的功能,不一樣的是,manage.py 設置好了 DJANGO_SETTINGS_MODULE 環境變量,因此在使用其它命令時比較方便,好比 python manage.py sql app1,若是使用 django-admin.py sql app1 的話,就須要先配置環境變量。因此,儘量使用 manage.py,但若是已經配置好環境變量,儘量使用 django-admin.py)
django-admin.py startproject project1
即會在當前目錄下新建一個名爲 project1 的目錄,此便可 web 項目名,目錄結構爲:
└── project1 ├── manage.py └── project1 ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
二、啓動服務:
使用項目根目錄下的 manage.py 腳原本啓動服務,該腳本的其它功能,可使用 python manage.py help 來查看。如 python manage.py shell 能夠進入配置好 django 環境變量的 python shell 環境,也能夠將 DJANGO_SETTINGS_MODULE 環境變量設置在 .bash_profile 文件中,就能夠直接使用 python 交互界面了。
python manage.py runserver
這樣啓動,是以 8000 端口爲服務端口,且只能本機訪問。若是須要其它機器也能夠訪問,且自定義端口號,可使用下面的方法:
python manage.py runserver 0.0.0.0:8000
django 自帶的 web 服務器對於開發很是方便,可是不要正式部署的時候還使用它,由於同一時間,該服務器只能可靠地處理一次單個請求,而且沒有進行任何類型的安全審計。須要正式部署的時候,仍是參考後面在Apache下的配置吧。
3、視圖和URL配置
添加視圖,在項目目錄下新建一個 view.py:
from django.http import HttpResponse def hellofun(request): return HttpResponse("Hello,World!")
配置URL,編輯 urls.py ,記得要引入 view.py 模塊。
from project1.view import * urlpatterns = patterns('', url(r'^hello/$', hellofun), )
^ 與 $ 分別是正則表達式,若是不加這兩個,則可能會匹配 /new/hello/old ,而用了 ^ 和 $ 限定的話,只能匹配 /hello/ ,很少也很多。r 表示是原始字符串,不把它當成轉義字符。
這樣在瀏覽器上訪問 http://211.152.52.112:8000/hello/ 能夠看到顯示 "Hello,World!" 的信息。可是 http://211.152.52.112:8000/ 會顯示找不到了,若是要給此網站根目錄的 URL 指定一個頁面,則須要使用相似 url(r'^$', hellofun)。
經過 runserver 啓動服務以後,腳本將於 manage.py 同目錄下查找 settings.py 文件,其中有一個 ROOT_URLCONF 的字段指向了 urls.py 。當用戶請求某一個URL時,django 根據 ROOT_URLCONF 的設置裝備 URLconf ,而後按順序匹配 URLconf 裏的 URLpatterns,直到找到一個匹配的,當找匹配的,就調用關聯的 view 函數,並把 HttpRequest 對象做爲第一個參數,並返回一個 HttpResponse 對象,django 再將這個 HttpResponse 對象包裝成HTTP協議格式返回給用戶。
若是須要動態配置URL,即傳一個參數給處理函數,可使用下面的方法,並在配置時加上 (),如:
url(r'^now/(\d{1,2})/$',now),
則相應的 view.py 裏應該以下:
from django.http import HttpResponse import datetime def now(request,offset): try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html="%s hour(s),it will be %s" %(offset,dt) return HttpResponse(html)
則請求如 http://211.152.52.112:8000/now/2/ 就會有相應顯示。
每一個視圖函數的第一個參數都是 HttpRequest 對象,offset 是可選參數,是從匹配的 URL 裏提取出來的,注意提取出來的值永遠是字符串類型,因此可能須要轉義(雖然此處在 urlconf 中已經可以保證傳入進來的是 int 類型,可是爲了鬆耦合,使此視圖代碼可使用在其它的地方,建議統一在此處再進行校驗)。
關於 django 調試,通常習慣使用 logging 模塊,能夠在 settings.py 中配置日誌輸出格式:
# 配置文志顯示的格式 import logging logging.basicConfig( #format = '\033[33m%(asctime)s \033[32m%(filename)s [line:%(lineno)d] \r\n\033[31m%(message)s\033[0m \r\n', # linux 下的設置 format = '%(asctime)s %(filename)s [line:%(lineno)d] \nlog: %(message)s \r\n', # windows 下的設置
datefmt = '%Y-%m-%d %H:%M:%S', )
此外,還能夠在須要調試的地方使用 assert False 來觸發出錯頁面,查看局部變量和程序語句,不過這種方法我用得不多。這種方式在 debug 模式下有效,即在 settings.py 中設置 DEBUG = True 時,注意!正式上線的項目, DEBUG 必定要設置爲 False,以防止暴露一些敏感信息。
4、模板
一、模板與上下文
兩個大括號包圍起來的文字,表示變量,如 {{ person_name }}、{{ ship_date | date:"F j,Y" }}
大括號和百分號包圍起來的文字,表示標籤,如 if 標籤和 for 標籤: {% if ordered_warranty %}、{% for item in item_list %}
先看一個 demo:
from django.template import * # 若是不是經過 python manage.py shell開啓解釋器交互模式,則須要加上下面兩句。另外也能夠設置 DJANGO_SETTINGS_MODULE 變量,或直接在 .bash_profile 或 bashrc 文件中添加下面兩句: # export PYTHONPATH=/root/django/project1 # export DJANGO_SETTINGS_MODULE=project1.settings from django.conf import settings settings.configure() str = """{% if sex %}His name is {{name}}.{% else %}Her name is {{name}}.{% endif %}""" t = Template(str) c = Context({'sex':1,'name':'tianya'}) print t.render(c) c = Context({'sex':0,'name':'feng'}) print t.render(c)
使用 Django 模板系統的基本流程:寫模板,建立 Template 對象,建立 Context,調用 render() 方法。
Django 模板解析很是快捷,大部分解析工做都是在後臺經過對簡短正則表達式一次性調用來完成,比基於 XML 的模板引擎要快幾個數量級。
除了字符串以外,Django 模板系統還能夠處理更復雜的數據結構,通常用句點符號 (.) 來實現。如:
str = "pet'name is {{ pet.0.name.upper }}" t = Template(str) person = {'name':'tianya','pet':[{'name':'tiger','age':2},{'name':'rabbit','age':1}]} c = Context(person) print t.render(c)
經過句點符號不只能夠調用字典結構的鍵值,還能夠調用數據的方法,如上面的 upper,可是因爲沒有使用圓括號,因此只能調用不須要參數的方法。此外,句點也能夠訪問列表索引,如上面的 pet.0 。
當模板系統在變量名中遇到句點符號時,會按如下順序進行查找:
字典鍵值、屬性、方法調用(只能調用不須要參數的方法)、列表索引(不容許使用負數),若是沒有查找到,則會顯示空字符串,而不會報錯。
模板系統不會執行任何以 functionname.alters_data = True 方式進行標記的方法。
二、基本模板標籤與過濾器
if 標籤中,空列表、空元組、空字典、空字符串、零值、特殊對象None、False對象都表示爲 False,其它均視爲 True。if 標籤能夠與 and , or , not 組合進行判斷,但不容許在同一標籤中同時使用 and 和 or,也不支持圓括號來組合比較操做。if 標籤必須使用 {% endif %} 來關閉每個 {% if %} 標籤。
ifequal/ifnotequal 標籤,用於比較兩個值是否相等,必須以 {% endifequal %} 或 {% endifnotequal %} 結束。該標籤只能比較字符串類型,整數類型和小數,不能布爾類型和其它複雜類型。
for 標籤中咱們在一個序列上迭代,且必須以 {% endfor %} 結束,給該標籤增長一個 reversed 可使得此序列被反向迭代,如: {% for item in mylist reversed %} ... {% endfor %}。在執行循環以前通常會用 if 標籤來檢測一下序列是否爲空,若是爲空,可能要輸出特定內容,因爲此操做十分常見,因此 for 標籤支持一個可選的 {% empty %} 分句,如:{% for item in mylist reversed %} ...{% empty %}There are no item. {% endfor %}。 for 標籤 break 和 continue 功能。在 for 標籤裏,有一個 forloop 模板變量,它有一些提示循環進度信息的屬性,如 forloop.counter 會記錄當前循環的執行次數,從1開始,若是習慣從0開始,也可使用 forloop.counter0;forloop.revconter 表示循環中剩餘項的個數,包括當前執行項,因此此值一開始是序列長度,最後一次循環中被置爲1,相似的還有 forloop.revcounter0,不包括當前執行項;此外還有 forloop.first 和 forloop.last ,分別表示,若是是否爲循環中第一項和是否爲循環中最後一項;forloop.parentloop 用於嵌套循環中,指向上一級循環的 forloop 對象的引用。
註釋標籤:{# This is a comment #},註釋的內容不會在模板渲染時輸出,但這種註釋不能跨多行,若是要實現多行註釋,可使用 comment 標籤,如 {% comment %} ... {% endcomment %}
過濾器是經過管道符號的,若是過濾器有參數,則參數跟隨冒號以後,且以雙引號包含。如 {{ str | truncatewords:"30" }} ,表示顯示變量 str 的前30個詞。
三、模板加載機制
建議將模板文件統一放到一個地方,如在應用文件夾 app1 下新建一個 templates 文件夾,而後配置 setting.py 文件,告知系統模板文件搜索路徑:
TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__),'app1/templates').replace('\\','/'), )
在 templates 文件夾下新建一個模板文件 curtime.html:
<html><body>It is now {{ curtime }}.</body></html>
編輯 app1/views.py:
#coding:utf-8 """ from django.shortcuts import render from django.http import HttpResponse from django.template.loader import get_template from django.template import Context import datetime def now(request): now = datetime.datetime.now() t = get_template('curtime.html') html = t.render(Context({'curtime':now})) return HttpResponse(html) """ from django.shortcuts import render_to_response import datetime def now(request): """ now = datetime.datetime.now() return render_to_response('curtime.html',{'curtime':now}) """ # 上面這種方法把模板加載、上下文建立、模板解析和HttpResponse建立工做均在 render_to_response() 的調用中完成了。而 render_to_response() 返回的 HttpResponse 對象正好能夠作爲 return 值。 curtime = datetime.datetime.now() return render_to_response('curtime.html',locals()) # locals() 返回的是當前函數執行到該點時,全部局部變量的名稱與值的映射字典。好比這裏還包括了 request。使用 locals() 注意變量名要起得跟模板文件中的變量名一致。是一種「偷懶」的寫法,代碼簡潔,可是,它包括的變量可能比你想象的要多,好比 request 對象。我的不推薦使用。
在 project1/urls.py 裏進行URL配置:
url(r'^admin/curtime$', now),
作好這一切以後,在瀏覽器中訪問 http://211.152.52.112:8000/admin/curtime 便可顯示當前時間。 至此,把前臺HTML代碼徹底分離出來了,已基本符合MVC模式。
接下來,解決網頁中的重複代碼問題,如大體相同的導航欄和底部欄,能夠在模板文件中經過 {% include 'header.html' %} 包含模板文件的方法。可是這樣有不少不便之處,好比兩個網頁的 <head>標籤中的<title>不同,那麼 head.html 可能須要這樣:<html><head><tile> ,而 </title></head> 卻須要另外再寫出,更優雅的方式是使用模板繼承。
先在 templates 目錄下建一個基本模板文件 base.html:
<html> <head> <title> {% block title %}{% endblock %} </title> </head> <body> <h1>Hello!</h1> {% block content %}This is content.{% endblock %} {% block footer %} <hr> <p>Bye!</p> {% endblock %} </body> </html>
block 標籤用於告訴模板引擎,子模板能夠重載這些部分,另block 標籤名不能重複。而後建一個模板文件 curtime1.html 繼承 base.html :
{% extends "base.html" %} {% block title %}The current time{% endblock %} {% block content %}
{{ block.super }} <p>It is now {{ curtime }}.</p> {% endblock %}
這裏注意 extends 標籤必須位於最上方,更精確的說,是必須爲模板中的第一個模板標記,不然繼承將不起做用。若是子模板沒有重載全部的 block 標籤,則未重載部分將使用基模板中指定的內容。若是要在子模板裏訪問基模板中塊的內容,可使用 {{ block.super }} 標籤
在瀏覽器中打開 http://211.152.52.112:8000/admin/curtime1 :
通常來講,基礎模板中的 {% block %} 標籤越多越好,由於子模板沒必要定義父模板中的全部代碼塊,也可使用父模板中的缺省值,鉤子天然是越多越好。
5、模型
默認 demo 是使用 sqlite3,改爲鏈接MYSQL數據庫,須要修改項目的 settings.py 文件:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django', 'USER': 'root', 'PASSWORD': '123456', 'HOST': '211.211.211.211', 'PORT': '3306', } }
而後進入 python manage.py shell 來測試數據庫鏈接是否正常:
from django.db import connection cursor = connection.cursor()
關於項目和應用:一般的作法是,project 是配置,而 app 是代碼,一個 project 包含不少 app 以及對它們的配置,另外 django 自己內建了一些 app,如註釋系統和自動管理界面,app 的優勢是很容易移植到其它 project 複用。
一個項目,能夠不建立應用,好比以前的全部的 demo 就是如此;但若是使用了模型,則必須建立一個 app,模型必須存放於 apps 中。
經過 manage.py 來新建一個應用:
python manage.py startapp app1
目錄結構:
├── app1
│ ├── admin.py
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── models.py
│ ├── models.pyc
│ ├── tests.py
│ └── views.py
django 使用MVC模式,首先來修改Model層,編輯 app1/models.py :
from django.db import models class User(models.Model): name = models.CharField(max_length=30) password = models.CharField(max_length=30) email = models.EmailField() def __unicode__(self): return '%s %s %s'%(self.name,self.password,self.email) class Meta: ordering=['-name','password']
在工程的 settings.py 中的 INSTALLED_APPS 字段中增長 'app1' 來安裝應用,可使用 django-admin.py validate 命令來檢查是否有問題,若是沒有問題,則執行:django-admin.py sql app1 能夠將 Model 層中的數據結構轉成SQL建表語句:
該命令只會輸出建表語句,而不會真正去更改數據庫,若是想提交至數據庫,可以使用 django-admin.py syncdb 命令,可是該命令不會將模型的修改或刪除同步到數據庫。
若是數據庫客戶端命令在環境變量中,則使用 django-admin.py dbshell 可直接調用相應的數據庫客戶端登入命令行模式。
而後新建一個 test.py 文件測試一下:
#coding=utf-8 from project1.app1.models import * #obj1 = User(name='tianya',password='123456',email='tianya@163.com',) #obj1.save() #User.objects.create(name='feng',password='123456',email='feng@163.com',) user_list =User.objects.all().order_by('-name','password') #從數據庫中取出全部對象,列表形式.以name逆序,其次以password排序,若不指定 order_by 方法,則默認以 User類中 class Meta: ordering=['-name','password'] 規則排序。 print user_list # 默認輸出形如:[<User: User object>, <User: User object>] ,能夠在 models.py 裏數據表類裏增長 __unicode__ 方法來改變輸出形式 user_list = User.objects.filter(name='tianya')[0:2] # 過濾,至關於SQL中where,而後再 選出其中[0,2]項 User.objects.filter(name='tianya').update(name='TianYa') # 找到相應對象,更新某一 字段 User.objects.all().update(password='654321') # 將全部用戶密碼更新 user_list = User.objects.filter(name__contains='tian') # 模糊查詢,SQL中like # __contains,包含 # __startswith,以...開頭 # __endswith,以...結尾 # __range,二者之間,至關於SQL中between try: str = 'tianya' user = User.objects.get(name=str) # 返回單個對象,若是有多個對象,或者沒有返回結 果,都會拋出異常 print user User.objects.get(name='tianya').delete() # 刪除查到的對象 except User.MultipleObjectsReturned: # 返回多個結果時的異常 print "Error: user'name = '%s' has multiple result." %str except User.DoesNotExist: # 沒有返回結果時的異常 print "Error: user'name = '%s' isn't in the DB." %str
6、Django 站點管理
一、簡介
Django自動管理工具是 django.contrib 工具包的一部分,後面咱們還會接觸到更多 django.contrib 包中的工具。
須要使用django自帶的後臺管理工具,首先要在 INSTALLED_APPS 里加入 django.contrib.admin,另外還須要加入 'django.contrib.auth','django.contrib.contenttypes'和'django.contrib.sessions' ,django.contrib.admin 須要這三個包(另外還有 'django.contrib.staticfiles' 是頁面渲染,即CSS和JS)。確保 MIDDLEWARE_CLASSES 包含 'django.middleware.common.CommonMiddleware'、'django.contrib.sessions.middleware.SessionMiddleware' 和 'django.contrib.auth.middleware.AuthenticationMiddleware' 。
作好上面的操做以後,先 django-admin.py syncdb 來生成後臺數據表到數據庫,此時會提示你建立一個後臺的超級用戶賬號,若是跳過,則須要經過 django-admin.py createsuperuser 來建立(只有安裝了 django.contrib.auth 應用以後再有些命令),而後配置URL規則,加上 url(r'^admin/', include(admin.site.urls)),而後瀏覽器中請求 http://127.0.0.1:8000/admin 便可訪問到後臺了。
二、加入本身的模塊
在你的應用目錄下建立一個 admin.py 文件,以下注冊模塊:
# coding=utf-8 from django.contrib import admin from project1.app1.models import * # Register your models here. class UserAdmin(admin.ModelAdmin): list_display = ('email','id','name','password',) # 設置依次顯示哪些字段 search_fields = ('id','name') # 搜索框 list_filter = ('email',) # 篩選器 ordering = ('id',) # 排序方式 fields = ('email','name','password') # 編輯頁面依次顯示哪些字段 admin.site.register(User,UserAdmin) # 註冊 User 模塊,以 UserAdmin 爲控制方案
經過後臺修改某個User時,全部的字段都默認要求不爲空,若是但願能夠爲空,能夠在 models.py 中設置 blank=True ,如 email = models.EmailField(blank=True),相似的還有 null=True、verbose_name='顯示名稱'(也能夠直接把別名寫在第一個參數,如 email = models.EmailField("e-mail",blank=True))
django 自帶的後臺管理平臺中,若是要使用本地語言,能夠在 MIDDLEWARE_CLASSES 中加上(但必須位於 'django.contrib.sessions.middleware.SessionMiddleware', 以後):
'django.middleware.locale.LocaleMiddleware',
三、自定義 admin
在應用的目錄下創建一個名爲 templates 的文件夾來存放咱們本身定義的模板文件。在 setting.py 裏增長如下代碼,告知模板載入器咱們自定義的模板目錄(manager 是應用名):
TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__),'manager/templates').replace('\\','/'), )
而後將jdango默認模板 django/contrib/admin/templates 中相應模板複製到自定義模板目錄下,如 django/contrib/admin/templates/admin/base_site.html 複製到 manager/templates/admin/base_site.html ,而後編輯它:
{% extends "admin/base.html" %} {% load i18n %} {% block title %}{{ title }} | {% trans '寵物大戰' %}{% endblock %} {% block branding %} <h1 id="site-name">{% trans '寵物大戰管理後臺' %}</h1> {% endblock %} {% block nav-global %}{% endblock %}
便可把默認模板的標題改爲本身想要的。想要修改默認模板的內容,就重複上面的動做,複製相應模板文件到自定義模板目錄,改寫便可,既然仍然要copy-paste,但仍然是可接受的。
當要重定義某特定 model 相關的模板文件時,如 change_form.html 等,假如應用名爲 PUser,則將 change_form.html 複製到 templates/admin/manager/puser/ 目錄下修改便可(注意!!!這裏使用應用名和model名的全小寫形式!)。總結一下,模板搜索順序是:
# 必須爲全小寫形式 templates/admin/app_name/model_name/change_form.html templates/admin/app_name/change_form.html templates/admin/change_form.html
除此以外,還能夠在 admin.py 文件裏編輯 class PUserAdmin:
class PUserAdmin(admin.ModelAdmin): change_form_template = "admin/my/puser/change_form.html"
其它相似的還有 change_list_template、delete_confirmation_template、object_history_template
關於模板載入器,能夠查看 /django/template/loaders/app_directories.py 裏的 load_template_source 方法,以及 django/contrib/admin/sites.py 中的 urls 配置。
django/contrib/admin/__init__.py 文件的 autodiscover() 方法迭代設置 INSTALLED_APPS 中的每一個應用程序,並查找名爲 admin.py 的文件
備註:我曾經遇到問題,爲了方便重寫模板,把 django/contrib/admin/ 作了名爲 admin 的軟連接放在應用目錄下,結果在從新啓動服務後,不管如何都沒法在後臺顯示 admin.py 裏註冊的數據了,把 admin 軟連接更名成 admin_source 後,(必需要再重啓服務),就正常了。
第十二章 部署 Django
修改 setting.py 文件中的 DEBUG 和 TEMPLATE_DEBUG 字段值爲 False,而後將 ALLOWED_HOSTS 字段設爲 ['*'],在模板文件夾中新建 404.html 和 500.html 來替代以前在DEBUG模式下django提供的相應錯誤頁面。
從 http://dist.modpython.org/dist/ 下載 mod_python 包,解壓進入目錄,執行:
./configure --with-apxs=/usr/local/apache2/bin/apxs --with-python=/usr/bin/python2.6 && make -j8 && make install
會在 /usr/local/apache/modules/ 目錄下生成 mod_python.so 文件。
從 http://code.google.com/p/modwsgi/ 下載 mod_wsgi ,解壓進入目錄,執行:
./configure --with-apxs=/usr/local/apache2/bin/apxs --with-python=/usr/bin/python2.6 && make -j8 && make install
會在 /usr/local/apache/modules/ 目錄下生成 mod_wsgi.so 文件。
在 /usr/local/apache2/htdocs/ 目錄下新建一個 django 項目,django-admin.py startproject project2,在項目目錄下會生動生成一個 wsgi.py 文件:
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project2.settings") from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
在文件裏增長兩行(不然當有多個項目時可能會有問題,因此加上比較好):
import sys sys.path.append('/usr/local/apache2/htdocs/project2')
配置 apache,編輯 httpd.conf :
LoadModule wsgi_module modules/mod_wsgi.so <VirtualHost *:80> WSGIScriptAlias /project2 "/usr/local/apache2/htdocs/project2/project2/wsgi.py" <Directory "/usr/local/apache2/htdocs/project2/project2"> Order Deny,Allow Allow from all </Directory> </VirtualHost>
django 調試:
使用 logging 模塊輸出日誌到終端中:
import logging logging.warning("this is error")
logging 日誌模塊的錯誤級別有 INFO,DEBUG,WARNING,ERROR,CRITICAL,默認級別是 WARING。若是須要配置 logging 默認配置,如默認級別,輸出到文件等,能夠編輯 setting.py:
logging.basicConfig( level = logging.DEBUG, format = '\033[33m%(asctime)s \033[32m%(filename)s [line:%(lineno)d]\r\n\033[31m%(message)s\033[0m\r\n', datefmt = '%Y-%m-%d %H:%M:%S', #filename = '/tmp/django.log', #filemode = 'w' )