python Django教程 之 安裝、基本命令、視圖與網站
一、簡介
Django 中提供了開發網站經常用到的模塊,常見的代碼都為你寫好了,通過減少重復的代碼,Django 使你能夠專注於 web 應用上有 趣的關鍵性的東西。為了達到這個目標,Django 提供了通用Web開發模式的高度抽象,提供了頻繁進行的編程作業的快速解決方法,以及為“如何解決問題”提供了清晰明了的約定。Django的理念是DRY(Don't Repeat Yourself)來鼓勵快速開發!
讓我們一覽 Django 全貌
urls.py
網址入口,關聯到對應的views.py中的一個函數(或者generic類),訪問網址就對應一個函數。
views.py
處理用戶發出的請求,從urls.py中對應過來, 通過渲染templates中的網頁可以將顯示內容,比如登陸后的用戶名,用戶請求的數據,輸出到網頁。
models.py
與數據庫操作相關,存入或讀取數據時用到這個,當然用不到數據庫的時候 你可以不使用。
forms.py
表單,用戶在瀏覽器上輸入數據提交,對數據的驗證工作以及輸入框的生成等工作,當然你也可以不使用。
templates 文件夾
views.py 中的函數渲染templates中的Html模板,得到動態內容的網頁,當然可以用緩存來提高速度。
admin.py
后台,可以用很少量的代碼就擁有一個強大的后台。
settings.py
Django 的設置,配置文件,比如 DEBUG 的開關,靜態文件的位置等。
二、安裝
在安裝Django之前,系統上必須已經安裝了Python,至於如何安裝Python,這里就不多講了
安裝好Python之后,建議安裝easy_install,這樣直接使用命令easy_install django即可下載最新版本,非常方便。
注意:以下方法中任何一種方法安裝都可,不用每個都試一次。
另外 建議自行安裝 bpython,這樣在用起來會爽很多。進入終端的時候輸入 bpython 可以有提示。當然也可以選擇用 ipython
一. 用 pip 來安裝
2.1 需要先安裝pip
(1). ubuntu:
sudo apt-get install python-pip
(2). RedHat
yum install python-pip
(3). Linux, Mac OSX, Windows 下都可用 get-pip.py 來安裝 pip:https://pip.pypa.io/en/latest/installing.html
或者直接下載:get-pip.py 然后運行在終端運行 python get-pip.py 就可以安裝 pip。
Note: 也可以下載 pip 源碼包,運行 python setup.py install 進行安裝
2.2 利用 pip 安裝 Django
(sudo) pip install Django 或者 (sudo) pip install Django==1.6.10 或者 pip install Django==1.7.6
如果想升級 pip 可以用:
(sudo) pip install --upgrade pip
Windows 用戶不要加 sudo,如果提示 ‘python’不是內部或外部命令,也不是可運行的程序或批處理文件。
那說明你的 Python 沒有安裝好,或者環境變量沒有配置正確,最簡單的辦法是安裝新版本的 Python 2.7.9, 里面集成了 pip,安裝時要勾選上環境變量這一個
二. 下載源碼安裝
https://www.djangoproject.com/download/
如果是源碼包, 比如 django-1.7.6.tar.gz
3.1 Linux 或 Mac 下
tar -xvzf django-1.7.6.tar.gz cd django-1.7.6 (sudo) python setup.py install
3.2 Windows 下
直接用解壓軟件解壓,然后到命令行(XP/Win7點擊開始,在下面的那個輸入框中輸入 cmd, Win8在開始那里點右鍵,選擇命令行)
比如在 D:\django-1.7.6\ 這個文件夾下
cd D: cd django-1.7.6 python setup.py install
什么?提示 ‘python’不是內部或外部命令,也不是可運行的程序或批處理文件。
那說明你的 Python 沒有安裝好,或者路徑沒有配置正確
Linux用自帶源進行安裝
1.1 ubuntu 下安裝 Django
sudo apt-get install python-django -y
1.2 redhat 下安裝用 yum
yum install python-django
注意:自帶源安裝的 Django 一般版本比較舊,而用 pip 可以安裝最新的版本。
2. 檢查是否安裝成功
終端上輸入 python ,點擊 Enter,進行 python 環境
1 >>> import django 2 >>> django.VERSION 3 (1, 7, 6, 'final', 0) 4 >>> 5 >>> django.get_version() 6 '1.7.6'
如果運行后看到版本號,就證明安裝成功了!
3. 擴展:搭建多個互不干擾的開發環境
我們有的時候會發現,一個電腦上有多個項目,一個依賴 Django 1.8,另一個比較舊的項目又要用 Django 1.5,這時候怎么辦呢?
我們需要一個依賴包管理的工具來處理不同的環境。
如果不想搭建這個環境,只想用某一個版本的 Django 也可以,但是推薦學習此內容!
3.1 環境搭建
開發會用 virtualenv 來管理多個開發環境,virtualenvwrapper 使得virtualenv變得更好用
# 安裝: (sudo) pip install virtualenv virtualenvwrapper
Linux/Mac OSX 下:
修改~/.bash_profile或其它環境變量相關文件(如 .bashrc 或用 ZSH 之后的 .zshrc),添加以下語句
export WORKON_HOME=$HOME/.virtualenvs export PROJECT_HOME=$HOME/workspace source /usr/local/bin/virtualenvwrapper.sh
修改后使之立即生效(也可以重啟終端使之生效):
source ~/.bash_profile
Windows 下:
pip install virtualenvwrapper-win
可選】Windows下默認虛擬環境是放在用戶名下面的Envs中的,與桌面,我的文檔,下載等文件夾在一塊的。更改方法:計算機,屬性,高級系統設置,環境變量,添加WORKON_HOME,如圖(windows 10 環境變量設置截圖):
3.2 使用方法:
mkvirtualenv zqxt:創建運行環境zqxt
workon zqxt: 工作在 zqxt 環境 或 從其它環境切換到 zqxt 環境
deactivate: 退出終端環境
其它的:
rmvirtualenv ENV:刪除運行環境ENV
mkproject mic:創建mic項目和運行環境mic
mktmpenv:創建臨時運行環境
lsvirtualenv: 列出可用的運行環境
lssitepackages: 列出當前環境安裝了的包
創建的環境是獨立的,互不干擾,無需sudo權限即可使用 pip 來進行包的管理。
1. 新建一個 django project
django-admin startproject project-name
一個 project 為一個項目,project-name 項目名稱,改成你自己的,要符合Python 的變量命名規則(以下划線或字母開頭)
2. 新建 app
python manage.py startapp app-name
或 django-admin.py startapp app-name
一般一個項目有多個app, 當然通用的app也可以在多個項目中使用。
3. 同步數據庫
python manage.py syncdb 注意:Django 1.7.1及以上的版本需要用以下命令 python manage.py makemigrations python manage.py migrate
這種方法可以創建表,當你在models.py中新增了類時,運行它就可以自動在數據庫中創建表了,不用手動創建。
備注:對已有的 models 進行修改,Django 1.7之前的版本的Django都是無法自動更改表結構的,不過有第三方工具 south,詳見 Django 數據庫遷移 一節。
4. 使用開發服務器
開發服務器,即開發時使用,一般修改代碼后會自動重啟,方便調試和開發,但是由於性能問題,建議只用來測試,不要用在生產環境。
python manage.py runserver # 當提示端口被占用的時候,可以用其它端口: python manage.py runserver 8001 python manage.py runserver 9999 (當然也可以kill掉占用端口的進程) # 監聽所有可用 ip (電腦可能有一個或多個內網ip,一個或多個外網ip,即有多個ip地址) python manage.py runserver 0.0.0.0:8000 # 如果是外網或者局域網電腦上可以用其它電腦查看開發服務器 # 訪問對應的 ip加端口,比如 http://172.16.20.2:8000
5. 清空數據庫
python manage.py flush
此命令會詢問是 yes 還是 no, 選擇 yes 會把數據全部清空掉,只留下空表。
6. 創建超級管理員
python manage.py createsuperuser # 按照提示輸入用戶名和對應的密碼就好了郵箱可以留空,用戶名和密碼必填 # 修改 用戶密碼可以用: python manage.py changepassword username
7. 導出數據 導入數據
python manage.py dumpdata appname > appname.json
python manage.py loaddata appname.json
關於數據操作 詳見后面數據導入和數據遷移內容,現在了解有這個用法就可以了。
8. Django 項目環境終端
python manage.py shell
如果你安裝了 bpython 或 ipython 會自動用它們的界面,推薦安裝 bpython。
這個命令和 直接運行 python 或 bpython 進入 shell 的區別是:你可以在這個 shell 里面調用當前項目的 models.py 中的 API,對於操作數據,還有一些小測試非常方便。
9. 數據庫命令行
python manage.py dbshell
Django 會自動進入在settings.py中設置的數據庫,如果是 MySQL 或 postgreSQL,會要求輸入數據庫用戶密碼。
在這個終端可以執行數據庫的SQL語句。如果您對SQL比較熟悉,可能喜歡這種方式。
10. 更多命令
終端上輸入 python manage.py 可以看到詳細的列表,在忘記子名稱的時候特別有用。
四、Django 視圖與網址
4.1 首先,新建一個項目(project), 名稱為 mysite
django-admin startproject mysite
備注:
1. 如果 django-admin 不行,請用 django-admin.py
2. 如果是在Linux是用源碼安裝的,或者用 pip 安裝的,也是用 django-admin.py 命令
運行后,如果成功的話, 我們會看到如下的目錄樣式
1 mysite 2 ├── manage.py 3 └── mysite 4 ├── __init__.py 5 ├── settings.py 6 ├── urls.py 7 └── wsgi.py
我們會發現執行命令后,新建了一個 mysite 目錄,其中還有一個 mysite 目錄,這個子目錄 mysite 中是一些項目的設置settings.py 文件,總的urls配置文件 urls.py 以及部署服務器時用到的 wsgi.py 文件, __init__.py 是python包的目錄結構必須的,與調用有關。
我們到外層那個 mysite 目錄下(不是mysite中的mysite目錄)
4.2新建一個應用(app), 名稱叫 learn
python manage.py startapp learn # learn 是一個app的名稱
我們可以看到mysite中多個一個 learn 文件夾,其中有以下文件。
1 learn/ 2 ├── __init__.py 3 ├── admin.py 4 ├── models.py 5 ├── tests.py 6 └── views.py
注:Django 1.8.x 以上的,還有一個 migrations 文件夾。Django 1.9.x 還會在 Django 1.8 的基礎上多出一個 apps.py 文件。但是這些都與本文無關。
把我們新定義的app加到settings.py中的INSTALL_APPS中
修改 mysite/mysite/settings.py
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'learn', )
備注,這一步是干什么呢? 新建的 app 如果不加到 INSTALL_APPS 中的話, django 就不能自動找到app中的模板文件(app-name/templates/下的文件)和靜態文件(app-name/static/中的文件) , 后面你會學習到它們分別用來干什么.
定義視圖函數(訪問頁面時的內容)
我們在learn這個目錄中,把views.py打開,修改其中的源代碼,改成下面的
#coding:utf-8 from django.http import HttpResponse def index(request): return HttpResponse(u"Hello World!")
第一行是聲明編碼為utf-8, 因為我們在代碼中用到了中文,如果不聲明就報錯.
第二行引入HttpResponse,它是用來向網頁返回內容的,就像Python中的 print 一樣,只不過 HttpResponse 是把內容顯示到網頁上。
我們定義了一個index()函數,第一個參數必須是 request,與網頁發來的請求有關,request 變量里面包含get或post的內容,用戶瀏覽器,系統等信息在里面(后面會講,先了解一下就可以)。
函數返回了一個 HttpResponse 對象,可以經過一些處理,最終顯示幾個字到網頁上。
那問題來了,我們訪問什么網址才能看到剛才寫的這個函數呢?怎么讓網址和函數關聯起來呢?
定義視圖函數相關的URL(網址) (即規定 訪問什么網址對應什么內容)
我們打開 mysite/mysite/urls.py 這個文件, 修改其中的代碼:
注:由於 Django 版本對 urls.py 進行了一些更改
Django 1.7.x 及以下的同學可能看到的是這樣的:
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^$', 'learn.views.index'), # new # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), )
Django 1.8.x及以上,Django 官方鼓勵(或說要求)先引入,再使用:
from django.conf.urls import url from django.contrib import admin from learn import views as learn_views # new urlpatterns = [ url(r'^$', learn_views.index), # new url(r'^admin/', admin.site.urls), ]
以上都修改並保存后,我們來看一下效果!
在終端上運行 python manage.py runserver 我們會看到類似下面的信息:
$ python manage.py runserver Performing system checks... System check identified no issues (0 silenced). You have unapplied migrations; your app may not work properly until they are applied. Run 'python manage.py migrate' to apply them. December 22, 2015 - 11:57:33 Django version 1.9, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
我們打開瀏覽器,訪問 http://127.0.0.1:8000/
不出意料的話會看到:
注意:如果是在另一台電腦上訪問要用 python manage.py ip:port 的形式,比如監聽所有ip:
python manage.py runserver 0.0.0.0:8000
監聽機器上所有ip 8000端口,訪問時用電腦的ip代替 127.0.0.1
Django中的 urls.py 用的是正則進行匹配的,如果不熟悉,您可以學習正則表達式以及Python正則表達式。
五、Django 視圖與網址進階
5.1在網頁上做加減法
5.1.1 采用 /add/?a=4&b=5 這樣GET方法進行
django-admin.py startproject zqxt_views
cd zqxt_views
python manage.py startapp calc
自動生成目錄大致如下(因不同的 Django 版本有一些差異,如果差異與這篇文章相關,我會主動提出來,沒有說的,暫時可以忽略他們之間的差異,后面的教程也是這樣做):
zqxt_views/ ├── calc │ ├── __init__.py │ ├── admin.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── zqxt_views ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
我們修改一下 calc/views.py文件
from django.shortcuts import render from django.http import HttpResponse def add(request): a = request.GET['a'] b = request.GET['b'] c = int(a)+int(b) return HttpResponse(str(c))
注:request.GET 類似於一個字典,更好的辦法是用 request.GET.get('a', 0) 當沒有傳遞 a 的時候默認 a 為 0
接着修改 zqxt_views/urls.py 文件,添加一個網址來對應我們剛才新建的視圖函數。
Django 1.7.x 及以下的同學可能看到的是這樣的:
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Examples: url(r'^add/$', 'calc.views.add', name='add'), # 注意修改了這一行 # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), )
Django 1.8.x及以上,Django 官方鼓勵(或說要求)先引入,再使用,低版本的 Django 也可以這樣用:
from django.conf.urls import url from django.contrib import admin from calc import views as calc_views urlpatterns = [ url(r'^add/', calc_views.add, name='add'), # 注意修改了這一行 url(r'^admin/', admin.site.urls), ]
我們打開開發服務器並訪問
python manage.py runserver 如果提示 Error: That port is already in use.在后面加上端口號8001,8888等 python manage.py runserver 8001
打開網址:http://127.0.0.1:8000/add/ 就可以看到
這是因為我們並沒有傳值進去,我們在后面加上 ?a=4&b=5,即訪問 http://127.0.0.1:8000/add/?a=4&b=5
就可以看到網頁上顯示一個 9,試着改變一下a和b對應的值試試看?
5.1.2 采用 /add/3/4/ 這樣的網址的方式
前面介紹的時候就說過 Django 支持優雅的網址
我們接着修改 calc/views.py文件,再新定義一個add2 函數,原有部分不再貼出
def add2(request, a, b): c = int(a) + int(b) return HttpResponse(str(c))
接着修改 zqxt_views/urls.py 文件,再添加一個新的 url
Django 1.7.x 及以下:
url(r'^add/(\d+)/(\d+)/$', 'calc.views.add2', name='add2'),
Django 1.8.x 及以上:
url(r'^add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
我們可以看到網址中多了 (\d+), 正則表達式中 \d 代表一個數字,+ 代表一個或多個前面的字符,寫在一起 \d+ 就是一個或多個數字,用括號括起來的意思是保存為一個子組(更多知識請參見 Python 正則表達式),每一個子組將作為一個參數,被 views.py 中的對應視圖函數接收。
我們再訪問 http://127.0.0.1:8000/add/4/5/ 就可以看到和剛才同樣的效果,但是這回網址更優雅了
5.2 url 中的 name [技能提升]
我們還有剛才的代碼,再來看一下 urls.py 中的代碼(注意:第二條改成了 add2)
from django.conf.urls import url from django.contrib import admin from calc import views as calc_views urlpatterns = [ url(r'^add/', calc_views.add, name='add'), url(r'^add2/(\d+)/(\d+)/$', calc_views.add2, name='add2'), url(r'^admin/', admin.site.urls), ]
url(r'^add/$', calc_views.add, name='add'), 這里的 name='add' 是用來干什么的呢?
我們在開發的時候,剛開始想用的是 /add2/4/5/ ,后來需求發生變化,比如我們又想改成 /4_add_5/這樣的格式,但是我們在網頁中,代碼中很多地方都寫死的是
<a href="/add2/4/5/">計算 4+5</a>
那么有沒有更優雅的方式來解決這個問題呢?當然答案是肯定的。
我們先說一下如何用 Python 代碼獲取對應的網址:
我們在終端上輸入(推薦安裝 bpython, 這樣Django會用 bpython的 shell)
C:\Users\Administrator\Desktop\文檔\day17\zqxt_views>python3.5 manage.py shell Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole)
>>> from django.core.urlresolvers import reverse >>> reverse('add2', args=(4,5)) '/add/4/5/' >>> reverse('add2', args=(444,555)) '/add/444/555/' >>>
reverse 接收 url 中的 name 作為第一個參數,我們在代碼中就可以通過 reverse() 來獲取對應的網址(這個網址可以用來跳轉,也可以用來計算相關頁面的地址),只要對應的 url 的name不改,就不用改代碼中的網址。
在網頁模板中也是一樣,可以很方便的使用。
不帶參數的: {% url 'name' %} 帶參數的:參數可以是變量名 {% url 'name' 參數 %} 例如: <a href="{% url 'add2' 4 5 %}">link</a>
上面的代碼渲染成最終的頁面是
<a href="/add2/4/5/">link</a>
這樣就可以通過 {% url 'add2' 4 5 %} 獲取到對應的網址 /add2/4/5/
當 urls.py 進行更改,前提是不改 name(這個參數設定好后不要輕易改),獲取的網址也會動態地跟着變,比如改成:
url(r'^new_add/(\d+)/(\d+)/$', 'calc.views.add2', name='add2'),
注意看重點 add2 變成了 new_add,但是后面的 name='add2' 沒改,這時 {% url 'add2' 4 5 %} 就會渲染對應的網址成 /new_add/4/5/
reverse 函數也是一樣,獲取的時候會跟着變成新的網址,這樣,在想改網址時只需要改 urls.py 中的正則表達式(url 參數第一部分),其它地方都“自動”跟着變了,是不是這樣更好呢?
另外,如何讓以前的 /add2/3/4/自動跳轉到新的網址呢?要知道Django不會幫你做這個,這個需要自己來寫一個跳轉方法:
具體思路是,在 views.py 寫一個跳轉的函數:
from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse def old_add2_redirect(request, a, b): return HttpResponseRedirect( reverse('add2', args=(a, b)) )
urls.py中:
url(r'^add2/(\d+)/(\d+)/$', calc_views.old_add2_redirect), url(r'^new_add/(\d+)/(\d+)/$', calc_views.add2, name='add2'),
這樣,假如用戶收藏夾中有 /add2/4/5/ ,訪問時就會自動跳轉到新的 /new_add/4/5/ 了
開始可能覺得直接寫網址簡單,但是用多了你一定會發現,用“死網址”的方法很糟糕