openstack開發實踐(二):Django框架簡介和Django應用的編寫

Django框架簡介

Django是Python最有代表性的一個網絡框架。使用Django可以方便地實現一個功能全面、管理簡便的網站或者APP後端。openstack中用來提供圖形化界面服務的Dashboard就是利用Django框架進行開發,所以在介紹openstack dashboard開發之前,通過本篇文章針對Django應用開發進行講解。
Django的MTV(模型-模板-視圖)模式本質上和一般MVC(模型-視圖-控制器)是一樣的。其中M代表模型(Model),負責業務對象和數據庫關係的映射,即ORM;T代表模板(Template),負責如何把頁面展示給用戶,即HTML;V代表視圖,負責業務邏輯,並在適當時候調用Model和Template。除了以上三層之外,還需要一個URL分發器、它的作用是將一個個URL的頁面請求,分發給不同的視圖處理,視圖再調用相應的數據模型和模板。MTV的響應模式如下圖所示:
在這裏插入圖片描述
1,Web服務器(中間件)收到一個http請求
2,Django在URLconf裏查找對應的視圖(View)函數來處理http請求
3,視圖函數調用相應的數據模型來存取數據、調用相應的模板向用戶展示頁面
4,視圖函數處理結束後返回一個http的響應給Web服務器
5,Web服務器將響應發送給客戶端

這種設計模式關鍵的優勢在於各種組件都是鬆耦合的。這樣,每個由 Django驅動的Web應用都有着明確的目的,並且可獨立更改而不影響到其它的部分。
比如,開發者更改一個應用程序中的 URL 而不用影響到這個程序底層的實現。設計師可以改變 HTML頁面的樣式而不用接觸Python代碼。
數據庫管理員可以重新命名數據表並且只需更改模型,無需從一大堆文件中進行查找和替換。
Django的MTV模式相對應的python文件如下:
在這裏插入圖片描述

Django簡單應用開發

爲了能夠更好地理解Django框架原理,我們通過Django開發一個簡單的web應用,來熟悉基於Django框架的web應用開發流程。該應用可以在客戶端進行靜態頁面展示,也可以在客戶端通過在網頁上提交表單的方法,修改服務器中數據庫的數據,並在網頁上可以查詢數據庫中的數據。其開發流程如下所示:

創建Django項目

通過devstack部署好all-in-one的openstack環境之後,Django也相應安裝完成,可以在想要創建Django項目文件夾的目錄下執行如下命令,創建Django項目,這裏我們設置Django的項目名爲mysite

django-admin.py startproject mysite

此時生成的mysite項目文件夾如下所示:
在這裏插入圖片描述

創建第一個頁面

下面通過創建一個簡單的靜態展示頁面來了解URLs分發和處理HTTP請求,首先需要將URL對應分配給某個對象處理,這需要在mysite/mysite下的urls.py設定。Python會根據該程序,將URL請求分給某個對象。urls.py的內容修改如下:


from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$','mysite.views.first_page'),
]

其中最後一行的作用是將根目錄的URL分配給一個對象進行處理,這個對象爲mysite/mysite下views.py中的first_page函數,目前views.py文件夾還不存在,需要我們自己創建並定義first_page函數,py文件內容如下:

# -*- coding: utf-8 -*-
from django.http import HttpResponse

def first_page(request):
    return HttpResponse("<p>第一個頁面</p>")

此時便可以啓動服務器查看該靜態頁面,在mysite目錄下使用如下命令啓動服務器:

./manage.py runserver 8080

此時通過訪問127.0.0.1:8080端口即可看到如下頁面:
在這裏插入圖片描述

增加一個app

一個網站可能有多個功能。可以在Django下,以app爲單位實現模塊化管理,而不是將所有的東西都放到一個文件夾下。在mysite下運行manage.py,創建新的名爲app_test的app:

python manage.py startapp app_test

該命令執行後,會在mysite目錄下生成app_test目錄,目錄文件結構如下所示:
在這裏插入圖片描述
要使用app_test,需要在mysite/setting.py的INSTALLED_APPS原組中增加app_test:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app_test',
)

我們可以爲該app增加一個靜態首頁。之前在mysite/urls.py中設置的URL訪問對象依然採用類似的方式設置。另一方面,實現模塊化,應該在app_test/urls.py中設置URL訪問對象。首先修改mysite/urls.py中的內容:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$','mysite.views.first_page'),
    url(r'^app_test/', include('app_test.urls')),
]

通過最後一行來訪問app_test,而對於app_test/下的訪問,則在app_test/urls.py中設置:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('',url(r'^$','app_test.views.first_page'),)

將URL對應到app_test下的views.py中的first_page函數(參考上面的first_page),
通過啓動服務器後訪問http://127.0.0.1:8080/app_test即可訪問該靜態頁面

使用數據庫

Django爲多種數據庫後臺提供了統一的調用API。根據需求不同,Django可以選擇不同的數據庫後臺。這裏將Django和MySQL連接。
首先在MySQL中創立Django項目的數據庫,爲Django項目創建用戶並授予相關權限,該用戶用戶名爲test,密碼爲test:

CREATE DATABASE django DEFAULT CHARSET=utf8;
GRANT ALL PRIVILEGES ON django.* TO 'test'@'localhost' IDENTIFIED BY 'test'

在mysite/setting.py中設置DATABASE對象如下:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER': 'test',
        'PASSWORD': 'test',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

Django根據setting中的設置,即可使用test用戶在數據庫中讀寫。MySQL作爲關係型數據庫,在Django的幫助下,可以不用直接編寫SQL語句。Django可以直接將關係型表(table)轉換成一個類(class),而每個記錄(record)是該類下的一個對象(object),這樣便可以使用基於對象的方法來操縱關係型數據庫MySQL。在傳統的MySQL中,數據模型是表;在Django下,一個表爲一個類,表的每一列都是該類的一個屬性。此次我們創建一個只有一列的表,即只有一個屬性的類,通過在app_test/models.py中添加該類:

from django.db import models

# Create your models here.

class Character(models.Model):
    name = models.CharField(max_length=200)
    def __unicode__(self):
        return self.name

該表只有一列,即name。
models.py修改完成之後,通過如下命令在MySQL中真正創建各個關係表

python manage.py syncdb
python manage.py makemigrations

此時通過test用戶進入MySQL的Django庫中即可看到表名爲app_test_character的表。我們在表中手動添加如下三條記錄:

INSERT INTO app_test_character (name) Values ("xiao ming");
INSERT INTO app_test_character (name) Values ("xiao zhang");
INSERT INTO app_test_character (name) Values ("xiao Fang");

下面通過代碼從數據庫中取出數據,並返回給HTTP請求。在app_test/views.py中添加視圖函數all(),從數據庫中讀取所有記錄然後返回客戶端:

# -*- coding: utf-8 -*-
from django.http import HttpResponse
from app_test.models import Character
def all(request):
    all_list = Character.objects.all()
    all_str = map(str,all_list)
    return HttpResponse("<p>"+' '.join(all_str)+"</p>")

可以看到,從app_test.models中引入Character類。通過操作該類,我們可以讀取表中的記錄。爲了能讓http請求能夠找到上面的數據,在app_test/urls.py中增加URL導航:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('',url(r'^$','app_test.views.first_page'),url(r'^all/','app_test.views.all'),)

運行服務器。在瀏覽器中輸入URL:127.0.0.1:8080/app_test/all/,可以在網頁上查看到該三條記錄

通過提交表單(POST)方法在頁面提交併存儲數據

在前面的內容中,我們採用手動的方式,直接在數據庫中插入數據。這裏將介紹通過提交表單(POST)方法來向後端服務器中的數據庫提交數據。我們採用POST方法,並用一個URL和處理函數,同時顯示視圖和處理請求。我們在app_test/views.py中創建處理函數investigate()。該函數可以通過Django提供的數據對象,對用戶提交的數據進行檢驗和處理之後存入數據庫的表中:

from django.http import HttpResponse
from app_test.models import Character
from django.shortcuts import render
from django.core.context_processors import csrf
from django import forms

class CharacterForm(forms.Form):
    name = forms.CharField(max_length = 200)
 
def investigate(request):
    if request.POST:
        form = CharacterForm(request.POST)
        if form.is_valid():
            submitted = form.cleaned_data['name']
            new_record = Character(name = submitted)
            new_record.save()

    form = CharacterForm()
    ctx = {}
    ctx.update(csrf(request))
    all_records = Character.objects.all()
    ctx['templay'] = all_records
    ctx['form'] = form
    return render(request,"app_test/investigate.html",ctx)

上面程序定義了CharacterForm類,並通過屬性name,說明了輸入欄name的類型爲字符串,最大長度爲200.而在investigate函數中,根據request的POST內容直接創立了form對象。該對象可以直接判斷輸入是否有效,並對輸入進行預處理。空白輸入被視爲無效。最後一行return使用render方法來代替之前使用的HttpResponse,ctx字典作爲模板app_test/investigate.html的參數,該模板文件位於mysite/templates/app_test/文件夾下(需要在根目錄mysite下新建templates文件夾),內容如下所示:

<form action="/app_test/investigate/" method="post">
    {% csrf_token %}
    {{form.as_p}}
<input type="submit" value="Submit">
</form>

{% for person in templay %}
<p>{{ person }}</p>
{% endfor %}

最後在app_test/urls.py中增加URL導航:

from django.conf.urls import patterns, include, url

urlpatterns = patterns('',url(r'^$','app_test.views.first_page'),
url(r'^all/','app_test.views.all'),
url(r'^investigate/','app_test.views.investigate'),)

運行服務器,輸入http://127.0.0.1:8080/app_test/investigate,會顯示如下內容,通過提交查詢可以將數據輸入並顯示錶中所有內容
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章