Python下有許多款不一樣的 Web 框架。Django是重量級選手中最有表明性的一位。許多成功的網站和APP都基於Django。html
Django是一個開放源代碼的Web應用框架,由Python寫成。python
Django遵照BSD版權,初次發佈於2005年7月, 並於2008年9月發佈了第一個正式版本1.0 。mysql
Django採用了MVC的軟件設計模式,即模型M,視圖V和控制器C。linux
在安裝 Django 前,系統須要已經安裝了Python的開發環境。接下來咱們來具體看下不一樣系統下Django的安裝。nginx
若是你還未安裝Python環境須要先下載Python安裝包。git
一、Python 下載地址:https://www.python.org/downloads/github
二、Django 下載地址:https://www.djangoproject.com/download/web
注意:目前Django 1.6.x以上版本已經徹底兼容Python 3.x。sql
安裝Python你只須要下載python-x.x.x.msi文件,而後一直點擊"Next"按鈕便可。數據庫
安裝完成後你須要設置Python環境變量。 右擊計算機->屬性->高級->環境變量->修改系統變量path,添加Python安裝地址,本文實例使用的是C:\Python33,你須要根據你實際狀況來安裝。
下載 Django 壓縮包,解壓並和Python安裝目錄放在同一個根目錄,進入 Django 目錄,執行python setup.py install,而後開始安裝,Django將要被安裝到Python的Lib下site-packages。
而後是配置環境變量,將這幾個目錄添加到系統環境變量中: C:/Python33/Lib/site-packages/django;C:/Python33/Scripts。 添加完成後就可使用Django的django-admin.py命令新建工程了。
輸入如下命令進行檢查:
python
import django django.get_version()
若是輸出了Django的版本號說明安裝正確。
如下安裝位於 Centos Linux 環境下安裝,若是是你的 Linux 系統是 ubuntu 請使用 apt-get 命令。
默認狀況下 Linux 環境已經支持了Python。你能夠在終端輸入Python命令來查看是否已經安裝。
Python 2.7.3 (default, Aug 1 2012, 05:14:39) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>
命令:
yum install setuptools
完成以後,就可使用 easy_install 命令安裝 django
easy_install django
以後咱們在python解釋器輸入如下代碼:
[root@solar django]# python Python 2.7.3 (default, May 15 2014, 14:49:08) [GCC 4.8.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import django >>> django.VERSION (1, 6, 5, 'final', 0) >>>
咱們能夠看到輸出了Django的版本號,說明安裝成功。
pip install Django
下載源碼包:https://www.djangoproject.com/download/
輸入如下命令並安裝:
tar xzvf Django-X.Y.tar.gz # 解壓下載包 cd Django-X.Y # 進入 Django 目錄 python setup.py install # 執行安裝命令
安裝成功後 Django 位於 Python 安裝目錄的 site-packages 目錄下。
從這裏下載最新的穩定版本:DJango-1.x.y.tar.gz,在頁面右側列表下載,以下圖:
記住是最新的官方版本哦.其中x.y是版本號。進入你下載該文件的文件夾目錄,執行以下命令:(Mac下默認是/Users/xxx/Downloads,xxx是你的用戶名)
$ tar zxvf Django-1.x.y.tar.gz
你也能夠從 Github 上下載最新版,地址:https://github.com/django/django:
git clone https://github.com/django/django.git
進入解壓後的目錄:
cd Django-1.x.y sudo python setup.py install
安裝成功後會輸出如下信息:
…… Processing dependencies for Django==1.x.y Finished processing dependencies for Django==1.x.y
再進入咱們的站點目錄,建立 Django 項目:
$ django-admin.py startproject testdj
啓動服務:
cd testdj # 切換到咱們建立的項目 $ python manage.py runserver …… Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
以上信息說明,項目已啓動,訪問地址爲http://127.0.0.1:8000/。
本章咱們將介紹Django 管理工具及如何使用 Django 來建立項目,第一個項目咱們以 HelloWorld 來命令項目。
安裝 Django 以後,您如今應該已經有了可用的管理工具 django-admin.py。咱們可使用 django-admin.py 來建立一個項目:
咱們能夠來看下django-admin.py的命令介紹:
[root@solar ~]# django-admin.py Usage: django-admin.py subcommand [options] [args] Options: -v VERBOSITY, --verbosity=VERBOSITY Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output --settings=SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used. --pythonpath=PYTHONPATH A directory to add to the Python path, e.g. "/home/djangoprojects/myproject". --traceback Raise on exception --version show program's version number and exit -h, --help show this help message and exit Type 'django-admin.py help <subcommand>' for help on a specific subcommand. Available subcommands: [django] check cleanup compilemessages createcachetable ……省略部分……
使用 django-admin.py 來建立 HelloWorld 項目:
django-admin.py startproject HelloWorld
建立完成後咱們能夠查看下項目的目錄結構:
[root@solar ~]# cd HelloWorld/ [root@solar HelloWorld]# tree . |-- HelloWorld | |-- __init__.py | |-- settings.py | |-- urls.py | `-- wsgi.py `-- manage.py
目錄說明:
接下來咱們進入 HelloWorld 目錄輸入如下命令,啓動服務器:
python manage.py runserver 0.0.0.0:8000
0.0.0.0讓其它電腦可鏈接到開發服務器,8000爲端口號。若是不說明,那麼端口號默認爲8000。
在瀏覽器輸入你服務器的ip及端口號,若是正常啓動,輸出結果以下:
在先前建立的 HelloWorld 目錄下的 HelloWorld 目錄新建一個 view.py 文件,並輸入代碼:
from django.http import HttpResponse def hello(request): return HttpResponse("Hello world ! ")
接着,綁定 URL 與視圖函數。打開 urls.py 文件,刪除原來代碼,將如下代碼複製粘貼到 urls.py 文件中:
from django.conf.urls import * from HelloWorld.view import hello urlpatterns = patterns("", ('^hello/$', hello), )
整個目錄結構以下:
[root@solar HelloWorld]# tree . |-- HelloWorld | |-- __init__.py | |-- __init__.pyc | |-- settings.py | |-- settings.pyc | |-- urls.py # url 配置 | |-- urls.pyc | |-- view.py # 添加的視圖文件 | |-- view.pyc # 編譯後的視圖文件 | |-- wsgi.py | `-- wsgi.pyc `-- manage.py
完成後,啓動 Django 開發服務器,並在瀏覽器訪問打開瀏覽器並訪問:
在上一章節中咱們使用 django.http.HttpResponse() 來輸出"Hello World!"。該方式將數據與視圖混合在一塊兒,不符合Django的MVC思想。
本章節咱們將爲你們詳細介紹 Django 模板的應用,模板是一個文本,用於分離文檔的表現形式和內容。
咱們接着上一章節的項目將在 HelloWorld 目錄底下建立 templates 目錄並創建 hello.html文件,整個目錄結構以下:
HelloWorld/ |-- HelloWorld | |-- __init__.py | |-- __init__.pyc | |-- settings.py | |-- settings.pyc | |-- urls.py | |-- urls.pyc | |-- view.py | |-- view.pyc | |-- wsgi.py | `-- wsgi.pyc |-- manage.py `-- templates `-- hello.html
hello.html 文件代碼以下:
<h1>{{ hello }}</h1>
從模板中咱們知道變量使用了雙括號。
接下來咱們須要向Django說明模板文件的路徑,修改HelloWorld/settings.py,修改 TEMPLATES 中的 DIRS 爲[BASE_DIR+"/templates",],以下所示:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR+"/templates",], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
咱們如今修改 view.py,增長一個新的對象,用於向模板提交數據:
# -*- coding: utf-8 -*- #from django.http import HttpResponse from django.shortcuts import render def hello(request): context = {} context['hello'] = 'Hello World!' return render(request, 'hello.html', context)
能夠看到,咱們這裏使用render來替代以前使用的HttpResponse。render還使用了一個字典context做爲參數。
context 字典中元素的鍵值 "hello" 對應了模板中的變量 "{{ hello }}"。
再訪問訪問http://192.168.45.3:8000/hello/,能夠看到頁面:
這樣咱們就完成了使用模板來輸出數據,從而實現數據與視圖分離。
接下來咱們將具體介紹模板中經常使用的語法規則。
基本語法格式以下:
{% if condition %} ... display {% endif %}
或者:
{% if condition1 %} ... display 1 {% elif condiiton2 %} ... display 2 {% else %} ... display 3 {% endif %}
根據條件判斷是否輸出。if/else 支持嵌套。
{% if %} 標籤接受 and , or 或者 not 關鍵字來對多個變量作判斷 ,或者對變量取反( not ),例如:
{% if athlete_list and coach_list %} athletes 和 coaches 變量都是可用的。 {% endif %}
{% for %} 容許咱們在一個序列上迭代。
與Python的 for 語句的情形相似,循環語法是 for X in Y ,Y是要迭代的序列而X是在每個特定的循環中使用的變量名稱。
每一次循環中,模板系統會渲染在 {% for %} 和 {% endfor %} 之間的全部內容。
例如,給定一個運動員列表 athlete_list 變量,咱們可使用下面的代碼來顯示這個列表:
<ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} </ul>
給標籤增長一個 reversed 使得該列表被反向迭代:
{% for athlete in athlete_list reversed %} ... {% endfor %}
能夠嵌套使用 {% for %} 標籤:
{% for athlete in athlete_list %} <h1>{{ athlete.name }}</h1> <ul> {% for sport in athlete.sports_played %} <li>{{ sport }}</li> {% endfor %} </ul> {% endfor %}
{% ifequal %} 標籤比較兩個值,當他們相等時,顯示在 {% ifequal %} 和 {% endifequal %} 之中全部的值。
下面的例子比較兩個模板變量 user 和 currentuser :
{% ifequal user currentuser %} <h1>Welcome!</h1> {% endifequal %}
和 {% if %} 相似, {% ifequal %} 支持可選的 {% else%} 標籤:8
{% ifequal section 'sitenews' %} <h1>Site News</h1> {% else %} <h1>No News Here</h1> {% endifequal %}
Django 註釋使用 {# #}。
{# 這是一個註釋 #}
模板過濾器能夠在變量被顯示前修改它,過濾器使用管道字符,以下所示:
{{ name|lower }}
{{ name }} 變量被過濾器 lower 處理後,文檔大寫轉換文本爲小寫。
過濾管道能夠被* 套接* ,既是說,一個過濾器管道的輸出又能夠做爲下一個管道的輸入:
{{ my_list|first|upper }}
以上實例將第一個元素並將其轉化爲大寫。
有些過濾器有參數。 過濾器的參數跟隨冒號以後而且老是以雙引號包含。 例如:
{{ bio|truncatewords:"30" }}
這個將顯示變量 bio 的前30個詞。
其餘過濾器:
{{ pub_date|date:"F j, Y" }}
{% include %} 標籤容許在模板中包含其它的模板的內容。
下面這兩個例子都包含了 nav.html 模板:
{% include "nav.html" %}
模板能夠用繼承的方式來實現複用。
接下來咱們先建立以前項目的 templates 目錄中添加 base.html 文件,代碼以下:
<html> <head> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> {% block mainbody %} <p>original</p> {% endblock %} </body> </html>
以上代碼中,名爲mainbody的block標籤是能夠被繼承者們替換掉的部分。
全部的 {% block %} 標籤告訴模板引擎,子模板能夠重載這些部分。
hello.html中繼承base.html,並替換特定block,hello.html修改後的代碼以下:
{% extends "base.html" %} {% block mainbody %} <p>繼承了 base.html 文件</p> {% endblock %}
第一行代碼說明hello.html繼承了 base.html 文件。能夠看到,這裏相同名字的block標籤用以替換base.html的相應block。
從新訪問地址http://192.168.45.3:8000/hello/,輸出結果以下:
Django 對各類數據庫提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。
Django 爲這些數據庫提供了統一的調用API。 咱們能夠根據本身業務需求選擇不一樣的數據庫。
MySQL 是 Web 應用中最經常使用的數據庫。本章節咱們將以 Mysql 做爲實例進行介紹。你能夠經過本站的 MySQL 教程 瞭解更多Mysql的基礎知識。
咱們在項目的 settings.py 文件中找到 DATABASES 配置項,將其信息修改成:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'test', 'PASSWORD': 'test123', 'HOST':'localhost', 'PORT':'3306', } }
上面包含數據庫名稱和用戶的信息,它們與MySQL中對應數據庫和用戶的設置相同。Django根據這一設置,與MySQL中相應的數據庫和用戶鏈接起來。
Django規定,若是要使用模型,必需要建立一個app。咱們使用如下命令建立一個 TestModel 的 app:
python manage.py startapp TestModel
目錄結構以下:
HelloWorld |-- TestModel | |-- __init__.py | |-- admin.py | |-- models.py | |-- tests.py | `-- views.py
咱們修改 TestModel/models.py文件,代碼以下:
# models.py from django.db import models class Test(models.Model): name = models.CharField(max_length=20)
以上的類名錶明瞭數據庫表名,且繼承了models.Model,類裏面的字段表明數據表中的字段(name),數據類型則由CharField(至關於varchar)、DateField(至關於datetime), max_length 參數限定長度。
接下來在settings.py中找到INSTALLED_APPS這一項,以下:
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'TestModel', # 添加此項 )
在命令行中運行python manage.py syncdb,看到幾行"Creating table…"的字樣,你的數據表就建立好了。
Creating tables ... …… Creating table TestModel_test #咱們自定義的表 ……
表名組成結構爲:app名_類名(如:TestModel_test)。
注意:儘管咱們沒有在models給表設置主鍵,可是Django會自動添加一個id做爲主鍵。
接下來咱們在 HelloWorld 目錄中添加 testdb.py 文件,並修改urls.py:
from django.conf.urls import * from HelloWorld.view import hello from HelloWorld.testdb import testdb urlpatterns = patterns("", ('^hello/$', hello), ('^testdb/$', testdb), )
添加數據須要先建立對象,而後再執行 save 函數,至關於SQL中的INSERT:
# -*- coding: utf-8 -*- from django.http import HttpResponse from TestModel.models import Test # 數據庫操做 def testdb(request): test1 = Test(name='w3cschool.cc') test1.save() return HttpResponse("<p>數據添加成功!</p>")
訪問http://192.168.45.3:8000/testdb/ 就能夠看到數據添加成功的提示。
Django提供了多種方式來獲取數據庫的內容,以下代碼所示:
# -*- coding: utf-8 -*- from django.http import HttpResponse from TestModel.models import Test # 數據庫操做 def testdb(request): # 初始化 response = "" response1 = "" # 經過objects這個模型管理器的all()得到全部數據行,至關於SQL中的SELECT * FROM list = Test.objects.all() # filter至關於SQL中的WHERE,可設置條件過濾結果 response2 = Test.objects.filter(id=1) # 獲取單個對象 response3 = Test.objects.get(id=1) # 限制返回的數據 至關於 SQL 中的 OFFSET 0 LIMIT 2; Test.objects.order_by('name')[0:2] #數據排序 Test.objects.order_by("id") # 上面的方法能夠連鎖使用 Test.objects.filter(name="w3cschool.cc").order_by("id") # 輸出全部數據 for var in list: response1 += var.name + " " response = response1 return HttpResponse("<p>" + response + "</p>")
輸出結果以下圖所示:
修改數據可使用 save() 或 update():
# -*- coding: utf-8 -*- from django.http import HttpResponse from TestModel.models import Test # 數據庫操做 def testdb(request): # 修改其中一個id=1的name字段,再save,至關於SQL中的UPDATE test1 = Test.objects.get(id=1) test1.name = 'w3cschool菜鳥教程' test1.save() # 另一種方式 #Test.objects.filter(id=1).update(name='w3cschool菜鳥教程') # 修改全部的列 # Test.objects.all().update(name='w3cschool菜鳥教程') return HttpResponse("<p>修改爲功</p>")
刪除數據庫中的對象只需調用該對象的delete()方法便可:
# -*- coding: utf-8 -*- from django.http import HttpResponse from TestModel.models import Test # 數據庫操做 def testdb(request): # 刪除id=1的數據 test1 = Test.objects.get(id=1) test1.delete() # 另一種方式 # Test.objects.filter(id=1).delete() # 刪除全部數據 # Test.objects.all().delete() return HttpResponse("<p>刪除成功</p>")
HTML表單是網站交互性的經典方式。 本章將介紹如何用Django對用戶提交的表單數據進行處理。
HTTP協議以"請求-回覆"的方式工做。客戶發送請求時,能夠在請求中附加數據。服務器經過解析請求,就能夠得到客戶傳來的數據,並根據URL來提供特定的服務。
咱們在以前的項目中建立一個 search.py 文件,用於接收用戶的請求:
# -*- coding: utf-8 -*- from django.http import HttpResponse from django.shortcuts import render_to_response # 表單 def search_form(request): return render_to_response('search_form.html') # 接收請求數據 def search(request): request.encoding='utf-8' if 'q' in request.GET: message = '你搜索的內容爲: ' + request.GET['q'].encode('utf-8') else: message = '你提交了空表單' return HttpResponse(message)
在模板目錄template中添加 search_form.html 表單:
<html> <head> <meta charset="utf-8" /> <title>Search - w3cschool.cc</title> </head> <body> <form action="/search/" method="get"> <input type="text" name="q"> <input type="submit" value="Search"> </form> </body> </html>
urls.py 規則修改成以下形式:
from django.conf.urls import * from HelloWorld.view import hello from HelloWorld.testdb import testdb from HelloWorld import search urlpatterns = patterns("", ('^hello/$', hello), ('^testdb/$', testdb), (r'^search-form/$', search.search_form), (r'^search/$', search.search), )
訪問地址:http://192.168.45.3:8000/search-form/並搜索,結果以下所示:
上面咱們使用了GET方法。視圖顯示和請求處理分紅兩個函數處理。
提交數據時更經常使用POST方法。咱們下面使用該方法,並用一個URL和處理函數,同時顯示視圖和處理請求。
咱們在tmplate 建立 post.html:
<html> <head> <meta charset="utf-8" /> <title>Search - w3cschool.cc</title> </head> <body> <form action="/search-post/" method="post"> {% csrf_token %} <input type="text" name="q"> <input type="submit" value="Submit"> </form> <p>{{ rlt }}</p> </body> </html>
在模板的末尾,咱們增長一個rlt記號,爲表格處理結果預留位置。
表格後面還有一個{% csrf_token %}的標籤。csrf全稱是Cross Site Request Forgery。這是Django提供的防止假裝提交請求的功能。POST方法提交的表格,必須有此標籤。
在HelloWorld目錄下新建 search2.py 文件並使用 search_post 函數來處理 POST 請求:
# -*- coding: utf-8 -*- from django.shortcuts import render from django.core.context_processors import csrf # 接收POST請求數據 def search_post(request): ctx ={} ctx.update(csrf(request)) if request.POST: ctx['rlt'] = request.POST['q'] return render(request, "post.html", ctx)
urls.py 規則修改成以下形式:
from django.conf.urls import * from HelloWorld.view import hello from HelloWorld.testdb import testdb from HelloWorld import search from HelloWorld import search2 urlpatterns = patterns("", ('^hello/$', hello), ('^testdb/$', testdb), (r'^search-form/$', search.search_form), (r'^search/$', search.search), (r'^search-post/$', search2.search_post), )
訪問 http://192.168.45.3:8000/search-post/ 顯示結果以下:
完成以上實例後,咱們的目錄結構爲:
HelloWorld |-- HelloWorld | |-- __init__.py | |-- __init__.pyc | |-- models.pyc | |-- search.py | |-- search.pyc | |-- search2.py | |-- search2.pyc | |-- settings.py | |-- settings.pyc | |-- testdb.py | |-- testdb.pyc | |-- urls.py | |-- urls.pyc | |-- view.py | |-- view.pyc | |-- wsgi.py | `-- wsgi.pyc |-- TestModel | |-- __init__.py | |-- __init__.pyc | |-- admin.py | |-- models.py | |-- models.pyc | |-- tests.py | `-- views.py |-- manage.py `-- templates |-- base.html |-- hello.html |-- post.html `-- search_form.html 3 directories, 29 files
每一個view函數的第一個參數是一個HttpRequest對象,就像下面這個hello()函數:
from django.http import HttpResponse def hello(request): return HttpResponse("Hello world")
HttpRequest對象包含當前請求URL的一些信息:
屬性 |
描述 |
path |
請求頁面的全路徑,不包括域名—例如, "/hello/"。 |
method |
請求中使用的HTTP方法的字符串表示。全大寫表示。例如: if request.method == 'GET': |
GET |
包含全部HTTP GET參數的類字典對象。參見QueryDict 文檔。 |
POST |
包含全部HTTP POST參數的類字典對象。參見QueryDict 文檔。 服務器收到空的POST請求的狀況也是有可能發生的。也就是說,表單form經過HTTP POST方法提交請求,可是表單中能夠沒有數據。所以,不能使用語句if request.POST來判斷是否使用HTTP POST方法;應該使用if request.method == "POST" (參見本表的method屬性)。 注意: POST不包括file-upload信息。參見FILES屬性。 |
REQUEST |
爲了方便,該屬性是POST和GET屬性的集合體,可是有特殊性,先查找POST屬性,而後再查找GET屬性。借鑑PHP's $_REQUEST。 例如,若是GET = {"name": "john"} 和POST = {"age": '34'},則 REQUEST["name"] 的值是"john", REQUEST["age"]的值是"34". 強烈建議使用GET and POST,由於這兩個屬性更加顯式化,寫出的代碼也更易理解。 |
COOKIES |
包含全部cookies的標準Python字典對象。Keys和values都是字符串。參見第12章,有關於cookies更詳細的講解。 |
FILES |
包含全部上傳文件的類字典對象。FILES中的每一個Key都是<input type="file" name="" />標籤中name屬性的值. FILES中的每一個value 同時也是一個標準Python字典對象,包含下面三個Keys:
注意:只有在請求方法是POST,而且請求頁面中<form>有enctype="multipart/form-data"屬性時FILES才擁有數據。不然,FILES 是一個空字典。 |
META |
包含全部可用HTTP頭部信息的字典。 例如:
META 中這些頭加上前綴HTTP_最爲Key, 例如:
|
user |
是一個django.contrib.auth.models.User 對象,表明當前登陸的用戶。 若是訪問用戶當前沒有登陸,user將被初始化爲django.contrib.auth.models.AnonymousUser的實例。 你能夠經過user的is_authenticated()方法來辨別用戶是否登陸:
if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users. 只有激活Django中的AuthenticationMiddleware時該屬性纔可用 |
session |
惟一可讀寫的屬性,表明當前會話的字典對象。只有激活Django中的session支持時該屬性纔可用。 參見第12章。 |
raw_post_data |
原始HTTP POST數據,未解析過。 高級處理時會有用處。 |
Request對象也有一些有用的方法:
方法 | 描述 |
---|---|
__getitem__(key) | 返回GET/POST的鍵值,先取POST,後取GET。若是鍵不存在拋出 KeyError。 這是咱們可使用字典語法訪問HttpRequest對象。 例如,request["foo"]等同於先request.POST["foo"] 而後 request.GET["foo"]的操做。 |
has_key() | 檢查request.GET or request.POST中是否包含參數指定的Key。 |
get_full_path() | 返回包含查詢字符串的請求路徑。例如, "/music/bands/the_beatles/?print=true" |
is_secure() | 若是請求是安全的,返回True,就是說,發出的是HTTPS請求。 |
在HttpRequest對象中, GET和POST屬性是django.http.QueryDict類的實例。
QueryDict相似字典的自定義類,用來處理單鍵對應多值的狀況。
QueryDict實現全部標準的詞典方法。還包括一些特有的方法:
方法 | 描述 |
---|---|
__getitem__ |
和標準字典的處理有一點不一樣,就是,若是Key對應多個Value,__getitem__()返回最後一個value。 |
__setitem__ |
設置參數指定key的value列表(一個Python list)。注意:它只能在一個mutable QueryDict 對象上被調用(就是經過copy()產生的一個QueryDict對象的拷貝). |
get() |
若是key對應多個value,get()返回最後一個value。 |
update() |
參數能夠是QueryDict,也能夠是標準字典。和標準字典的update方法不一樣,該方法添加字典 items,而不是替換它們: >>> q = QueryDict('a=1') >>> q = q.copy() # to make it mutable >>> q.update({'a': '2'}) >>> q.getlist('a') ['1', '2'] >>> q['a'] # returns the last ['2'] |
items() |
和標準字典的items()方法有一點不一樣,該方法使用單值邏輯的__getitem__(): >>> q = QueryDict('a=1&a=2&a=3') >>> q.items() [('a', '3')] |
values() |
和標準字典的values()方法有一點不一樣,該方法使用單值邏輯的__getitem__(): |
此外, QueryDict也有一些方法,以下表:
方法 | 描述 |
---|---|
copy() |
返回對象的拷貝,內部實現是用Python標準庫的copy.deepcopy()。該拷貝是mutable(可更改的) — 就是說,能夠更改該拷貝的值。 |
getlist(key) |
返回和參數key對應的全部值,做爲一個Python list返回。若是key不存在,則返回空list。 It's guaranteed to return a list of some sort.. |
setlist(key,list_) |
設置key的值爲list_ (unlike __setitem__()). |
appendlist(key,item) |
添加item到和key關聯的內部list. |
setlistdefault(key,list) |
和setdefault有一點不一樣,它接受list而不是單個value做爲參數。 |
lists() |
和items()有一點不一樣, 它會返回key的全部值,做爲一個list, 例如: >>> q = QueryDict('a=1&a=2&a=3') >>> q.lists() [('a', ['1', '2', '3'])]
|
urlencode() |
返回一個以查詢字符串格式進行格式化後的字符串(e.g., "a=2&b=3&b=5").
|
Django 提供了基於 web 的管理工具。
Django自動管理工具是django.contrib的一部分。你能夠在項目的 settings.py 中的INSTALLED_APPS看到它:
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', )
django.contrib是一套龐大的功能集,它是Django基本代碼的組成部分。
一般咱們在生成項目時會在urls.py中自動設置好,咱們只需去掉註釋便可。
配置項以下所示:
from django.contrib import admin admin.autodiscover() # And include this URLpattern... urlpatterns = patterns('', # ... (r'^admin/', include(admin.site.urls)), # ... )
當這一切都配置好後,Django管理工具就能夠運行了。
啓動開發服務器,而後在瀏覽器中訪問:http://yoursite:8000/admin/,獲得以下界面:
你能夠經過命令 python manage.py createsuperuser 來建立超級用戶,以下所示:
# python manage.py createsuperuser Username (leave blank to use 'root'): admin Email address: admin@w3cschool.cc Password: Password (again): Superuser created successfully. [root@solar HelloWorld]#
以後輸入用戶名密碼登陸,界面以下:
爲了讓admin界面管理某個數據模型,咱們須要先註冊該數據模型到admin。好比,咱們以前在 TestModel 中已經建立了模型 Test 。修改 TestModel/admin.py:
from django.contrib import admin from TestModel.models import Test # Register your models here. admin.site.register(Test)
刷新後便可看到 Testmodel 數據表:
管理頁面的功能強大,徹底有能力處理更加複雜的數據模型。
先在 TestModel/models.py 中增長一個更復雜的數據模型:
from django.db import models # Create your models here. class Contact(models.Model): name = models.CharField(max_length=200) age = models.IntegerField(default=0) email = models.EmailField() def __unicode__(self): return self.name class Tag(models.Model): contact = models.ForeignKey(Contact) name = models.CharField(max_length=50) def __unicode__(self): return self.name
這裏有兩個表。Tag以Contact爲外部鍵。一個Contact能夠對應多個Tag。
咱們還能夠看到許多在以前沒有見過的屬性類型,好比IntegerField用於存儲整數。
在 TestModel/admin.py 註冊多個模型並顯示:
from django.contrib import admin from TestModel.models import Test,Contact,Tag # Register your models here. admin.site.register([Test, Contact, Tag])
刷新管理頁面,顯示結果以下:
在以上管理工具咱們就能進行復雜模型操做。
咱們能夠自定義管理頁面,來取代默認的頁面。好比上面的"add"頁面。咱們想只顯示name和email部分。修改 TestModel/admin.py:
from django.contrib import admin from TestModel.models import Test,Contact,Tag # Register your models here. class ContactAdmin(admin.ModelAdmin): fields = ('name', 'email') admin.site.register(Contact, ContactAdmin) admin.site.register([Test, Tag])
以上代碼定義了一個ContactAdmin類,用以說明管理頁面的顯示格式。
裏面的fields屬性定義了要顯示的字段。
因爲該類對應的是Contact數據模型,咱們在註冊的時候,須要將它們一塊兒註冊。顯示效果以下:
咱們還能夠將輸入欄分塊,每一個欄也能夠定義本身的格式。修改TestModel/admin.py爲:
from django.contrib import admin from TestModel.models import Test,Contact,Tag # Register your models here. class ContactAdmin(admin.ModelAdmin): fieldsets = ( ['Main',{ 'fields':('name','email'), }], ['Advance',{ 'classes': ('collapse',), # CSS 'fields': ('age',), }] ) admin.site.register(Contact, ContactAdmin) admin.site.register([Test, Tag])
上面的欄目分爲了Main和Advance兩部分。classes說明它所在的部分的CSS格式。這裏讓Advance部分隱藏:
Advance部分旁邊有一個 Show 按鈕,用於展開,展開後可點擊 Hide 將其隱藏,以下圖所示:
上面的Contact是Tag的外部鍵,因此有外部參考的關係。
而在默認的頁面顯示中,將二者分離開來,沒法體現出二者的從屬關係。咱們可使用內聯顯示,讓Tag附加在Contact的編輯頁面上顯示。
修改TestModel/admin.py:
from django.contrib import admin from TestModel.models import Test,Contact,Tag # Register your models here. class TagInline(admin.TabularInline): model = Tag class ContactAdmin(admin.ModelAdmin): inlines = [TagInline] # Inline fieldsets = ( ['Main',{ 'fields':('name','email'), }], ['Advance',{ 'classes': ('collapse',), 'fields': ('age',), }] ) admin.site.register(Contact, ContactAdmin) admin.site.register([Test])
顯示效果以下:
在Contact輸入數條記錄後,Contact的列表頁看起來以下:
咱們也能夠自定義該頁面的顯示,好比在列表中顯示更多的欄目,只須要在ContactAdmin中增長list_display屬性:
from django.contrib import admin from TestModel.models import Test,Contact,Tag # Register your models here. class ContactAdmin(admin.ModelAdmin): list_display = ('name','age', 'email') # list admin.site.register(Contact, ContactAdmin) admin.site.register([Test, Tag])
刷新頁面顯示效果以下:
搜索功能在管理大量記錄時很是有,咱們可使用search_fields爲該列表頁增長搜索欄:
from django.contrib import admin from TestModel.models import Test,Contact,Tag # Register your models here. class ContactAdmin(admin.ModelAdmin): list_display = ('name','age', 'email') search_fields = ('name',) admin.site.register(Contact, ContactAdmin) admin.site.register([Test])
在本實例中咱們搜索了 name 爲 w3cschool.cc(本站域名) 的記錄,顯示結果以下:
Django Admin 管理工具還有很是多實用的功能,感興趣的同窗能夠深刻研究下。
在前面的章節中咱們使用 python manage.py runserver 來運行服務器。這隻適用測試環境中使用。
正式發佈的服務,咱們須要一個能夠穩定而持續的服務器,好比apache, Nginx, lighttpd等,本文將以 Nginx 爲例。
Centos 下安裝步驟以下:
yum groupinstall "Development tools" yum install zlib-devel bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel
CentOS 自帶 Python 2.4.3,但咱們能夠再安裝Python2.7.5:
cd ~ wget http://python.org/ftp/python/2.7.5/Python-2.7.5.tar.bz2 tar xvf Python-2.7.5.tar.bz2 cd Python-2.7.5 ./configure --prefix=/usr/local make && make altinstall
easy_install包 https://pypi.python.org/pypi/distribute
安裝步驟:
cd ~ wget https://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz tar xf distribute-0.6.49.tar.gz cd distribute-0.6.49 python2.7 setup.py install easy_install --version
pip包: https://pypi.python.org/pypi/pip
安裝pip的好處是能夠 pip list、pip uninstall 管理Python包, easy_install 沒有這個功能,只有uninstall
uwsgi:https://pypi.python.org/pypi/uWSGI
uwsgi參數詳解:http://uwsgi-docs.readthedocs.org/en/latest/Options.html
pip install uwsgi uwsgi --version #查看 uwsgi 版本
測試uwsgi是否正常:
新建test.py文件,內容以下:
def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return "Hello World"
而後在終端運行:
uwsgi --http :8001 --wsgi-file test.py
在瀏覽器內輸入:http://127.0.0.1:8001,查看是否有"Hello World"輸出,若沒有輸出,請檢查你的安裝過程。
pip install django
測試django是否正常,運行:
django-admin.py startproject demosite cd demosite python2.7 manage.py runserver 0.0.0.0:8002
在瀏覽器內輸入:http://127.0.0.1:8002,檢查django是否運行正常。
安裝命令以下:
cd ~ wget http://nginx.org/download/nginx-1.5.6.tar.gz tar xf nginx-1.5.6.tar.gz cd nginx-1.5.6 ./configure --prefix=/usr/local/nginx-1.5.6 \ --with-http_stub_status_module \ --with-http_gzip_static_module make && make install
你能夠閱讀 Nginx 安裝配置 瞭解更多內容。
uwsgi支持ini、xml等多種配置方式,本文以 ini 爲例, 在/ect/目錄下新建uwsgi9090.ini,添加以下配置:
[uwsgi] socket = 127.0.0.1:9090 master = true //主進程 vhost = true //多站模式 no-site = true //多站模式時不設置入口模塊和文件 workers = 2 //子進程數 reload-mercy = 10 vacuum = true //退出、重啓時清理文件 max-requests = 1000 limit-as = 512 buffer-size = 30000 pidfile = /var/run/uwsgi9090.pid //pid文件,用於下面的腳本啓動、中止該進程 daemonize = /website/uwsgi9090.log
找到nginx的安裝目錄(如:/usr/local/nginx/),打開conf/nginx.conf文件,修改server配置:
server { listen 80; server_name localhost; location / { include uwsgi_params; uwsgi_pass 127.0.0.1:9090; //必須和uwsgi中的設置一致 uwsgi_param UWSGI_SCRIPT demosite.wsgi; //入口文件,即wsgi.py相對於項目根目錄的位置,「.」至關於一層目錄 uwsgi_param UWSGI_CHDIR /demosite; //項目根目錄 index index.html index.htm; client_max_body_size 35m; } }
你能夠閱讀 Nginx 安裝配置 瞭解更多內容。
設置完成後,在終端運行:
uwsgi --ini /etc/uwsgi9090.ini & /usr/local/nginx/sbin/nginx
在瀏覽器輸入:http://127.0.0.1,你就能夠看到django的"It work"了。