1. 程式人生 > >python後臺架構Django開發全解

python後臺架構Django開發全解

全棧工程師開發手冊 (作者:欒鵬)

我的使用環境win8+python3.6+pycharm+django2.0

博主使用的是anaconda佩戴的python3.6,所以python的位置在anaconda的安裝目錄下。

安裝完django後,在G:\anaconda\Scripts下存在管理工具django-admin.py、django-admin.exe檔案。

安裝

pip install django

設定環境變數

將django包的目錄新增大系統環境變數path下。由於博主使用的anaconda,所以安裝目錄在anaconda資料夾下

G:\anaconda
\Lib\site-packages\django G:\anaconda\Scripts

新增到環境變數path下。

驗證是否成功

cmd中輸入

python
import django
print(django.get_version())

建立一個伺服器專案

1、使用cmd建立Django專案。

重新開啟cmd,cd到你儲存的目錄,使用如下命令建立一個django伺服器專案。

django-admin startproject hello

這將在目錄下生成一個hello目錄,也就是你的這個Django專案的根目錄。它包含了一系列自動生成的目錄和檔案,具備各自專有的用途。注意:在給專案命名的時候必須避開Django和Python的保留關鍵字,比如“django”,“test”等,否則會引起衝突和莫名的錯誤。對於hello的放置位置,不建議放在傳統的/var/wwww目錄下,它會具有一定的資料暴露危險,因此Django建議你將專案檔案放在例如/home/mycode類似的位置。

2、pycharm中建立Django專案。

選單欄開啟“檔案”-“新建專案”-選擇Django專案。

這裡寫圖片描述

一個新建立的專案結構大概如下:

hello/
    manage.py
    hello/
        __init__.py
        settings.py
        urls.py
        wsgi.py

詳細解釋(很重要):

外層的hello/目錄與Django無關,只是你專案的容器,可以任意命名。

內層的hello/目錄是真正的專案檔案包裹目錄,它的名字是你引用內部檔案的包名,例如:hello.urls。

hello/init.py:一個定義包的空檔案。

hello/settings.py:專案的主配置檔案,非常重要!

hello/urls.py:路由檔案,所有的任務都是從這裡開始分配,相當於Django驅動站點的內容表格,非常重要!

hello/wsgi.py:一個基於WSGI的web伺服器進入點,提供底層的網路通訊功能,通常不用關心。

Django專案配置

Django專案的設定檔案位於settings.py檔案中。這個檔案,集合了整個專案方方面面的設定屬性,是專案啟動和提供服務的根本保證。

我們先初步修改setting.py中的下面幾個配置項,其他的保持不變。

# 白名單
ALLOWED_HOSTS = ['*']  #*表示允許所有主機訪問網站

# 國際化和本地化配置
LANGUAGE_CODE = 'zh-Hans'   # 簡體中文

TIME_ZONE = 'Asia/Shanghai'  #時區 為上海

USE_I18N = False # 指定Django的翻譯系統是否開啟

USE_L10N = False  # 是否開啟資料本地化

USE_TZ = False #是否使用指定的時區(TIME_ZONE)的時間

刪除MIDDLEWARE中的下面元素,因為容易產生訪問失敗。

'django.middleware.csrf.CsrfViewMiddleware',   #取消校驗

啟動伺服器

1、cmd中啟動伺服器專案。

cd進入hello目錄,輸入下面的命令:

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.
September 07, 2016 - 15:50:53
Django version 1.10, using settings `mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Django提供了一個用於開發的web伺服器,使你無需配置一個類似Ngnix的線上伺服器,就能讓站點執行起來。但你也不要將開發伺服器用於生產環境,它只是一個簡易的測試伺服器。
現在,在瀏覽器訪問http://127.0.0.1:8000/,你將看到Django的歡迎陰面,一切OK!

這裡寫圖片描述

django開發伺服器(以後省略)預設執行在內部的8000埠,如果你想指定,請在命令中顯示給出,例如:

python manage.py runserver 0.0.0.0:8000

上面:Django將執行在8000埠,整個子網內都將可以訪問,而不是本機。
注意: Django的開發伺服器具有自動過載功能,當你的程式碼有修改,每隔一段時間伺服器將自動更新。但是,有一些例如增加檔案的動作,不會觸發伺服器過載,這時就需要你自己手動重啟。

2、pycharm中啟動伺服器專案。

如果你不喜歡直接在cmd視窗中輸入很長的命令,你可以用pycharm開啟專案hello。並且開啟檔案manage.py。在選單欄“執行”,選擇“編輯結構”

這裡寫圖片描述

直接在Script parameters中輸入指令碼引數runserver,選中“顯示這個頁面”

這裡寫圖片描述

這樣我們就可以在pycharm中除錯Django專案了。

以後我們均使用pycharm來輸入引數除錯Django專案。

建立功能app模組

app與project的區別:

一個app實現某個功能,比如部落格、公共檔案資料庫或者簡單的投票系統;
一個project是配置檔案和多個app的集合,他們組合成整個站點;
一個project可以包含多個app;
一個app可以屬於多個project!
app的存放位置可以是任何地點,但是通常我們將它們都放在與manage.py同級目錄下,這樣方便匯入檔案。

我們在pycharm中使用如下的指令碼引數啟動manage.py來建立一個功能模組app1

startapp app1

系統會自動生成 app1目錄,其結構如下:

app1/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

將功能模組新增的專案設定中,只有將專案註冊到專案中,自定義的功能模組才能被系統識別呼叫。

修改hello資料夾下setting.py檔案,將新建的功能模組名app1新增到INSTALLED_APPS 陣列中。

INSTALLED_APPS = [
    'app1',  #將自定義模組註冊到專案中
    'django.contrib.admin',  #admin站點
    'django.contrib.auth',  #身份認證系統
    'django.contrib.contenttypes', #內容型別框架
    'django.contrib.sessions', #會話框架
    'django.contrib.messages', #訊息框架
    'django.contrib.staticfiles', #靜態檔案管理框架
]

Django伺服器專案連線資料庫

Django預設使用內建的SQLite資料庫。當然,如果你是在建立一個實際的專案,請使用類似MySql的生產用資料庫,避免以後面臨資料庫切換的頭疼。

按照參考教程我們配置自己的資料庫連線設定。

# 資料庫配置
DATABASES = {
    'default': {
            'ENGINE': 'django.db.backends.mysql',  #資料庫驅動名
            'NAME': 'xxxxxx', #資料庫名稱
            'USER': 'xxxxxx',  # 使用者名稱
            'PASSWORD': 'xxxxx', #密碼
            'HOST': '127.0.0.1', #IP地址
            'PORT': '3306',  # 埠號
        }
}

設定完後我們使用runserver重新啟動伺服器專案,如果沒有報錯,這證明連線成功。

Django的MTV結構

首先說說Web伺服器開發領域裡著名的MVC模式,所謂MVC就是把Web應用分為模型(M),控制器(C)和檢視(V)三層,他們之間以一種外掛式的、鬆耦合的方式連線在一起,模型負責業務物件與資料庫的對映(ORM),檢視負責與使用者的互動(頁面),控制器接受使用者的輸入呼叫模型和檢視完成使用者的請求,其示意圖如下所示:

這裡寫圖片描述

Django的MTV模式本質上和MVC是一樣的,也是為了各元件間保持鬆耦合關係,只是定義上有些許不同,Django的MTV分別是值:

M 代表模型(Model):負責業務物件和資料庫的關係對映(ORM)。

T 代表模板 (Template):負責如何把頁面展示給使用者(html)。

V 代表檢視(View):負責業務邏輯,並在適當時候呼叫Model和Template。

這裡寫圖片描述

——————————————————

上面我們已經知道了如何連線資料庫,如果進行伺服器專案的設定,下面我們就可以根據業務進行後臺架構了。

這裡先對下面的工作做一下概括。

1、資料模型Model部分,將構造物件的結構和資料庫的結構。

2、檢視View部分,根據內容使用者請求,返回資料給前端或傳給模板。

3、模板Template部分,接收檢視函式傳遞的引數,渲染html頁面傳給使用者。

4、地址對映urls部分,將不同的網址,對映到不同的功能模組或不同的檢視函式。

1、資料模型models

Django通過自定義python類的形式來定義具體的模型,每個模型代表資料庫中的一張表,每個類的例項代表資料表中的一行資料,類中的每個變數代表資料表中的一列欄位。Django通過ORM對資料庫進行操作,奉行程式碼優先的理念,將python程式設計師和資料庫管理員進行分工解耦。

按照參考文章中的教程,我們在app1模組中建立user和diary兩個資料模型。

from django.db import models
# 設定物件結構(對應資料庫的結構)
class User(models.Model):
    username = models.CharField(max_length=200)  # 字串型別欄位
    password = models.CharField(max_length=200,null=True)  # 整數型別欄位,null=True允許為空
    age = models.IntegerField(default=0)  # 整數型別欄位
    date = models.DateField('date registered',auto_now=True)  # 時間型別欄位,引數為人類可讀的欄位名

    # 模型的元資料Meta
    class Meta:  # 注意,是模型的子類,要縮排!
        db_table = 'user'

class Diary(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)  # 外來鍵。
    content = models.TextField()  # 文字型別欄位

    # 模型的元資料Meta
    class Meta:  # 注意,是模型的子類,要縮排!
        db_table = 'diary'

使用命令啟用模型

python manage.py makemigrations app1
python manage.py migrate

這裡寫圖片描述

2、編寫檢視views

檢視的實現在每個功能模組的views.py檔案中實現。在app1/view.py中每個函式接收request引數,request中包含前臺請求資料。views.py中的函式通過請求資料進行邏輯運算,讀寫資料庫等過程獲取響應資料。將響應資料以字串、物件、或html檢視的形式返回。

由於檢視函式多需要呼叫模板來返回渲染的頁面,而我們還沒有詳細學習模板的語法。所以我們這裡在app1/views.py中先增加兩個簡單檢視函式。

  • index函式,返回hello world字串
  • finduser函式,返回使用者物件字典
from django.http import HttpResponse,JsonResponse,Http404
from .models import User,Diary
from django.shortcuts import render_to_response,render,redirect,reverse,HttpResponseRedirect,get_object_or_404
from django.template import Context,loader
from django.forms.models import model_to_dict
import time

# 接收請求資料返回字串響應。http://127.0.0.1:8000/app1/
def index(request):
    return HttpResponse("Hello, world")   # 直接返回響應字串

# 返回字典或json字串
def finduser(request):
    try:
        userid = request.GET.get("userid", None)  # 讀取資料
        users = User.objects.filter(id=userid)  # 獲取一個使用者,返回QuerySet
        user = users[0]  # 獲取第一個user物件
        user_dict1 = model_to_dict(user)  # 將物件轉化為字典
        return JsonResponse(user_dict1)  # 返回前端字典
    except:
        raise Http404("使用者不存在")

3、模板層templates

在檢視函式中我們可以返回的形式多種多樣,其中我們最需要的就是根據查詢到的資料,動態生成頁面返回給前端。(移動網際網路時代下起始直接傳遞所需物件資料才是最常用的)

每一個Web框架都需要一種很便利的方法用於動態生成HTML頁面。 最常見的做法是使用模板。

模版是純文字檔案,可以生成任何基於文字的檔案格式,比如HTML,XML,CSV等。模板檔案位於每個app的templates資料夾下,沒有此資料夾可以手動建立。

模板包含所需HTML頁面的靜態部分,以及一些特殊的模版語法,用於將動態內容插入靜態部分。

地址對映urls

為了根據不同是網址呼叫不同的檢視,我們還需要編寫urls檔案。這是路由檔案,根據使用者開啟的網址對應到不同的檢視函式。

前面的教程我們已經建立了hello這個Django專案和app1這個功能模組。為了方便學習後面的教程,這裡我們再建立一個功能模組app2。

案例

學習了model模型層、views檢視層、templates模板層、static靜態資源、urls路由對映,我們就可以來新增我們的檢視函式和模板頁面的設計了。

還是以上面的hello為專案名,

構建路徑:

在app1資料夾下新建templates/app1/模板目錄。
在app1資料夾下新建static/app1/靜態資源目錄。

這裡寫圖片描述

在templates/app1/目錄下新增insert.html、oneuser.html、showuser.html三個模板檔案。

我們在app1的views.py檔案新增5個函式:

  • index函式,作為首頁,只響應一個hello world的字串。
  • insertuser函式,包含了返回增加使用者頁面和將使用者輸入加入到資料庫後重定向兩個功能。
  • finduser函式,根據指定的userid查詢使用者,不過返回字典物件
  • findalluser函式,獲取所有使用者,渲染成頁面。
  • detail函式,查詢指定userid的使用者,返回網頁。

我們配置hello專案的根路由為

from django.conf.urls import include,url  # Django1.11中的語法
from django.urls import path,include  #Django2中的語法
from django.contrib import admin

urlpatterns = [
    # url是一個函式。regex和view為必填引數。regex就是使用者輸入的內容,view就是對應的檢視生成函式
    url(r'^vip/', admin.site.urls),  # Django自帶的超級管理員後臺地址。不要用臺隨意的網址
    url(r'^app1/', include('app1.urls')),  # 對映到下級路由
    path(r'^app2/', include('app2.urls')),  # 對映到下級路由
]

配置app1應用的路由為

from django.conf.urls import url  # Django1.11中的語法
from django.urls import path  #Django2中的語法
from . import views
from django.views.generic import RedirectView

app_name = 'app1_name'  # 關鍵是這行,這樣對不同app下相同名稱的url就可以進行區分了。{% url 'app1:inserpath' %}

urlpatterns = [
    url(r'^$', views.index, name='index'),  # ^$正則表示為空,ex:http://127.0.0.1:8000/app1/
    url(r'^insert/', views.insertuser,name='inserpath'),  # 直接對映到函式
    url(r'^alluser/', views.findalluser,name='alluserpath'),  # 直接對映到函式
    url(r'^finduser/', views.finduser),  # 直接對映到函式
    # url通過(?P<name>pattern)來接收引數。因此(?P<userid>[0-9]+)就是一個引數。重定向到這個url時需要傳遞這個引數,url才能完整生成。
    # ex:reverse('app1_name:detail', args=11) 生成網址/app1/11/detail/
    url(r'^(?P<userid>[0-9]+)/detail/$', views.detail, name='detail'),
    path('userid/<int:userid>/', views.detail),
]

這樣一個基本的網站就搭建完成了。下面我們來開始對網站進行測試。

自動化測試

自動化測試工作在功能模組的tests.py檔案中實現