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的响应模式如下图所示:
openstack开发实践(二):Django框架简介和Django应用的编写_第1张图片
1,Web服务器(中间件)收到一个http请求
2,Django在URLconf里查找对应的视图(View)函数来处理http请求
3,视图函数调用相应的数据模型来存取数据、调用相应的模板向用户展示页面
4,视图函数处理结束后返回一个http的响应给Web服务器
5,Web服务器将响应发送给客户端

这种设计模式关键的优势在于各种组件都是松耦合的。这样,每个由 Django驱动的Web应用都有着明确的目的,并且可独立更改而不影响到其它的部分。
比如,开发者更改一个应用程序中的 URL 而不用影响到这个程序底层的实现。设计师可以改变 HTML页面的样式而不用接触Python代码。
数据库管理员可以重新命名数据表并且只需更改模型,无需从一大堆文件中进行查找和替换。
Django的MTV模式相对应的python文件如下:
openstack开发实践(二):Django框架简介和Django应用的编写_第2张图片

Django简单应用开发

为了能够更好地理解Django框架原理,我们通过Django开发一个简单的web应用,来熟悉基于Django框架的web应用开发流程。该应用可以在客户端进行静态页面展示,也可以在客户端通过在网页上提交表单的方法,修改服务器中数据库的数据,并在网页上可以查询数据库中的数据。其开发流程如下所示:

创建Django项目

通过devstack部署好all-in-one的openstack环境之后,Django也相应安装完成,可以在想要创建Django项目文件夹的目录下执行如下命令,创建Django项目,这里我们设置Django的项目名为mysite

django-admin.py startproject mysite

此时生成的mysite项目文件夹如下所示:
openstack开发实践(二):Django框架简介和Django应用的编写_第3张图片

创建第一个页面

下面通过创建一个简单的静态展示页面来了解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("

第一个页面

"
)

此时便可以启动服务器查看该静态页面,在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目录,目录文件结构如下所示:
openstack开发实践(二):Django框架简介和Django应用的编写_第4张图片
要使用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("

"+' '.join(all_str)+"

"
)

可以看到,从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,会显示如下内容,通过提交查询可以将数据输入并显示表中所有内容
openstack开发实践(二):Django框架简介和Django应用的编写_第5张图片
openstack开发实践(二):Django框架简介和Django应用的编写_第6张图片

你可能感兴趣的:(openstack开发实践)