使用Python3.4和Django来构建Web应用程序(第二部分:应用开发篇)

总结

继上次环境搭建之后,本次我们将使用Django创建Web应用程序。

如果您想了解环境搭建,请参考上一篇文章。
Python3.4 + Django构建Web应用程序(第1部分:环境搭建)

用Django制作Web应用

Django中存在着”项目”表示整个服务的单位,以及”应用”表示服务的一个功能的单位。
项目和应用的范围并没有严格定义,但是模型是根据每个应用来定义的,
实际的数据库将在整个项目中共享。

在这里我们将使用”pj1″作为项目名称,并且用”app1″作为应用程序名称来创建。
作为一个Web应用程序的例子,我们将创建一个用来管理IP地址使用情况的应用程序。
注意,我们将在/vagrant目录下创建Django项目,然后使用主机上的文本编辑器编辑应用程序文件。

生成Django项目

首先,我们要创建一个Django项目。

(venv_app1) [vagrant@localhost ~]$ cd /vagrant/django_apps/
(venv_app1) [vagrant@localhost django_apps]$

(venv_app1) [vagrant@localhost django_apps]$ django-admin startproject pj1

(venv_app1) [vagrant@localhost django_apps]$ ls -al
total 0
drwxr-xr-x 1 vagrant vagrant 136 Sep 18 14:36 .
drwxr-xr-x 1 vagrant vagrant 204 Sep 18 10:47 ..
drwxr-xr-x 1 vagrant vagrant 136 Sep 18 14:36 pj1
drwxr-xr-x 1 vagrant vagrant 272 Sep 18 06:12 venv_app1

生成项目后,将创建以下目录。

pj1/
|-- manage.py
`-- pj1
    |-- __init__.py
    |-- settings.py
    |-- urls.py
    `-- wsgi.py

pj1/pj1目录下的文件集是适用于所有应用程序的共用配置文件。

在pj1目录下自动生成的manage.py是一个程序,它具有许多方便的功能,可以用于使用Django开发Web应用。

例如,Django具有启动开发用简易Web服务器的功能。通过这个功能,即使没有ngix等Web服务器,也可以在Web浏览器中确认开发中的应用程序。
通过以下命令,可以启动简易Web服务器。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py runserver 0.0.0.0:8000

启动后,您可以在主机上的网络浏览器中输入以下URL进行尝试。

http://192.168.33.15:8000/

一旦成功,您就可以在Web浏览器中查看下面的界面。

django_snapshot.png

Django项目的初始设置

我们将进行整个应用程序所共有的Django项目的初始设置。

我們將繼續編輯 pj1/pj1/settings.py。

(venv_app1) [vagrant@localhost]$ cd /vagrant/django_apps/
(venv_app1) [vagrant@localhost django_apps]$ vi pj1/pj1/settings.py
# 追加・削除した部分のみを記載しています。

# データベースはデフォルトでSQLiteが設定されているため、MySQLに変更する
 DATABASES = {
    'default': {

        # 以下を削除
        #'ENGINE': 'django.db.backends.sqlieete3',
        #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

        # 作成したデータベース情報を追記
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'app1_db',
        'USER': 'app1_user',
        'PASSWORD': 'app1_passwd',
        'HOST': 'localhost',
        'PORT': '3306',
    }
 }

(中略)

# 言語設定を英語から日本語に変更

# 以下を削除
# LANGUAGE_CODE = 'en-us'
# TIME_ZONE = 'UTC'

#以下を追記
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'

修改pj1/pj1/settings.py后,语言设置变为了日语。您可以再次启动简易Web服务器,并在主机上的Web浏览器中进行查看。您可以确认默认的Django Web页面已切换为日语显示。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py runserver 0.0.0.0:8000
django_ja_snapshot.png

以上是Django项目的初始设定完成。

初始化数据库

为了初始化数据库,请执行以下命令。执行后,将生成一个名为「app1_db」的数据库上的管理表的SQL语句。在这个过程中,您需要以对话形式输入管理员信息。在这里,我们随意创建了ID:admin,Pass:admin,e-mail:无。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py migrate

Would you like to create one now? (yes/no): yes
Username (leave blank to use 'vagrant'): admin
Email address: (無記入でEnter)
Password: admin
Password (again): admin

如果您想增加管理员用户,则可以通过执行以下命令来执行与上述对话模式相同的操作模式。

$ python pj1/manage.py createsuperuser

当我们登录MariaDB并查看数据库时,可以确认Django所需的数据表已经被创建。

(venv_app1) [vagrant@localhost django_apps]$  mysql -u app1_user -papp1_passwd

MariaDB [app1_db]> USE app1_db;
Database changed

MariaDB [app1_db]> SHOW TABLES;
+----------------------------+
| Tables_in_app1_db          |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
10 rows in set (0.00 sec)

执行上述操作后,Django 管理网站将会自动生成。
请启动简易Web服务器,并在主机的Web浏览器中进行确认。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py runserver 0.0.0.0:8000
http://192.168.33.15:8000/admin/

然后将显示以下管理网站。

django_admin_snapshot.png

在Web浏览器中输入先前输入的管理员信息(此处为ID:admin,PASS:admin),即可进入管理网站。

django_admin_login.png

在这个管理页面上,您可以添加管理员用户和组,而无需直接触碰数据库。

在Django中,不仅仅是用户管理,还可以在管理站点中添加、修改和删除数据库的所有信息。
这样,即使不需要自己创建专用应用程序,Django也会自动创建数据库管理功能,这是Django非常方便的一点。

生成Django应用程序

接下来,我们将创建一个Django应用程序。

(venv_app1) [vagrant@localhost django_apps]$ cd /vagrant/django_apps/pj1/
(venv_app1) [vagrant@localhost pj1]$ python manage.py startapp app1

生成应用程序后,将在pj1目录下创建app1目录。pj1/pj1目录下的文件集是所有应用程序共享的配置文件,而pj1/app1目录下的文件集则是Django应用程序独有的配置文件。

pj1/
|-- app1
|   |-- __init__.py
|   |-- admin.py
|   |-- migrations
|   |   `-- __init__.py
|   |-- models.py
|   |-- tests.py
|   `-- views.py
|-- manage.py
`-- pj1
    |-- __init__.py
    |-- __pycache__
    |   |-- __init__.cpython-34.pyc
    |   `-- settings.cpython-34.pyc
    |-- settings.py
    |-- urls.py
    `-- wsgi.py

定义模型

首先,我们会定义模型并定义数据库表结构,然后开始构建应用程序。

在Django中,需要修改每个应用程序目录下的models.py文件,将表格定义为类,并将字段定义为变量。

模型要求

在这里,我们假设创建一个用于管理IP地址的应用程序,并定义以下模型。

    • IPアドレスの利用状況を管理するアプリケーション

IP addressテーブル
IP addressフィールド

所有するIPv4アドレス群を示す
ネットワークセグメントは無視して、/32のアドレス単体を管理
値は一意

Statusフィールド

IPアドレスの利用状況のステータスを保持
in_use / avalable / not_available の3つの状態を持つ
ブランクの状態は許可しない

Descriptionフィールド

IPアドレスの利用状況についてのメモ
自由記述可
ブランクの状態を許可する

编辑models.py

为了满足模型要求,将pj1/app1/models.py编辑如下:
通过准备一个状态候选列表status_list,您可以在管理站点或Web应用中使用下拉菜单来进行选择。

from django.db import models

class Ipaddress(models.Model):

    status_list = (
        ('in_use', 'in use'),
        ('available', 'available'),
        ('not_available', 'not available')
    )
    ipaddress = models.GenericIPAddressField(verbose_name='IP address', unique=True)
    status = models.CharField(verbose_name='Status', choices=status_list, max_length=16)
    description = models.CharField(verbose_name='Discription', blank = True, max_length=255)

激活 Django 应用程序的模型定义。

然后,对Django项目启用”app1″模型定义。

在pj1/pj1/settings.py中添加到”INSTALLED_APPS”中。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/pj1/settings.py
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    #アプリケーション名を追記
    'app1'
 )

将模型定义反映到数据库中。

下一步是将添加的模型同步到数据库中。

使用以下命令将数据库和差异内容转换为SQL语句并执行。
(此时并没有实际执行SQL语句。)

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py makemigrations app1

Migrations for 'app1':
  0001_initial.py:
    - Create model IPaddress

您可以使用以下命令确认已发出的SQL语句。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py sqlmigrate app1 0001

BEGIN;
CREATE TABLE `app1_ipaddress` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `ipaddress` char(39) NOT NULL UNIQUE, `status` varchar(16) NOT NULL, `description` varchar(255) NOT NULL);

COMMIT;

接下来,您可以使用以下命令执行生成的SQL语句。这一步会更新数据库。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py migrate

Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: admin, app1, auth, contenttypes, sessions
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying app1.0001_initial... OK

查询MariaDB,可以确认已添加新表「app1_ipaddress」。

(venv_app1) [vagrant@localhost django_apps]$ mysql -u app1_user -papp1_passwd

MariaDB [(none)]> USE app1_db;
Database changed

MariaDB [app1_db]> SHOW TABLES;
+----------------------------+
| Tables_in_app1_db          |
+----------------------------+
| app1_ipaddress              |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
11 rows in set (0.00 sec)

每次编辑`models.py`文件时,通过执行两个命令`python pj1/manage.py makemigrations app1`和`python pj1/manage.py migrate`来改变数据库。

在管理网站中注册应用程序所用的数据表

数据库已更新,但是目前在管理网站上尚未添加app1所用的表格。
为了在管理网站上进行管理,需要编辑app1目录下的admin.py文件。

vi pj1/app1/admin.py
from django.contrib import admin

# 追記
from app1.models import Ipaddress

# 追記
admin.site.register(Ipaddress)

开设一个简单的Web服务器,并使用宿主机的Web浏览器来查看管理网站。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py runserver 0.0.0.0:8000
http://192.168.33.15:8000/admin/

在Django管理网站中,将显示app1的表格信息。

django_admin_app1_regist_snapshot.png

只需要输入数据并点击“添加”按钮,就可以将数据添加到IP地址表中。

接下来,我们将使用管理网站来注册三个IP地址信息。

IP address : 192.168.0.0
Status: not_available
Discription: Network address

IP address : 192.168.0.1
Status: available
Discription: (blank)

IP address : 192.168.0.2
Status: available
Discription: (blank)

在管理网站上输出已注册信息,需要在models.py中添加str函数。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/models.py
from django.db import models

class Ipaddress(models.Model):
    status_list = (
        ('in_use', 'in use'),
        ('available', 'available'),
        ('not_available', 'not available')
    )
    ipaddress = models.GenericIPAddressField(verbose_name='IP address', unique=True)
    status = models.CharField(verbose_name='Status', choices=status_list, max_length=16)
    description = models.CharField(verbose_name='Discription', blank = True, max_length=255)

    # ここを追加
    def  __str__(self):
        return self.ipaddress

按照这样的方法,可以显示IP地址表中的内容。

django_admin_app1_regist2_snapshot.png

另外,如果要显示IP地址表的字段信息,请编辑admin.py。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/admin.py
from django.contrib import admin
from app1.models import Ipaddress

# 以下を追加
class IpaddressAdmin(admin.ModelAdmin):
    list_display = ('ipaddress', 'status', 'description')

admin.site.register(Ipaddress, IpaddressAdmin)

通过这样做,您可以自定义管理站点的显示。

django_admin_app1_regist3_snapshot.png

为了确保,我会在实际数据库中核实地址信息是否已正确添加。

(venv_app1) [vagrant@localhost django_apps]$ mysql -u app1_user -papp1_passwd

MariaDB [(none)]> USE app1_db;

MariaDB [app1_db]> SELECT * FROM app1_ipaddress;
+----+-------------+--------------+-----------------+
| id | ipaddress   | status       | description     |
+----+-------------+--------------+-----------------+
|  1 | 192.168.0.0 | not_avilable | Network address |
|  2 | 192.168.0.1 | available    |                 |
|  3 | 192.168.0.2 | available    |                 |
+----+-------------+--------------+-----------------+
3 rows in set (0.00 sec)

通过这种方式,在Django中可以通过管理网站来添加和删除记录信息,而无需使用SQL命令。

将Tips数据库的记录信息写入到文本文件中。

在处理数据库时,会出现需要将当前信息写入的场景。
Django提供了将数据库记录信息以JSON/XML/YAML其中一种格式进行导出的功能。
在这里,我们选择以JSON格式进行导出。

(venv_app1) [vagrant@localhost django_apps]$ mkdir pj1/app1/dumpdata

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py dumpdata app1 --format=json --indent=2 -o pj1/app1/dumpdata/ap1_db_dump.json
(venv_app1) [vagrant@localhost django_apps]$ cat pj1/app1/dumpdata/ap1_db_dump.json
[
{
  "pk": 1,
  "fields": {
    "status": "not_avilable",
    "ipaddress": "192.168.0.0",
    "description": "Network address"
  },
  "model": "app1.ipaddress"
},
{
  "pk": 2,
  "fields": {
    "status": "available",
    "ipaddress": "192.168.0.1",
    "description": ""
  },
  "model": "app1.ipaddress"
},
{
  "pk": 3,
  "fields": {
    "status": "available",
    "ipaddress": "192.168.0.2",
    "description": ""
  },
  "model": "app1.ipaddress"
}
]

如果将创建的文件用git进行管理,就可以按时间顺序管理记录信息。
另外,如果想要读取导出的文件,请执行以下命令。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py loaddata pj1/app1/dumpdata/ap1_db_dump.json

Installed 3 object(s) from 1 fixture(s)

定义Django应用程序的View

因为模型部分已经完成,下一步是创建决定Django应用程序显示的视图。

定义URL

首先,我们要定义Web应用程序的URL。
通过编辑pj1/pj1/ulrs.py文件来定义Django应用程序的URL。
当需要定义每个Django应用程序的页面等更具体的URL时,
我们需要创建并添加一个位于应用程序目录下的urls.py文件。

首先,我们需要修改pj1/pj1/ulrs.py文件。
在这里,我们将设置以下URL为有效:
http://192.168.33.15:8000/app1/

 (venv_app1) [vagrant@localhost django_apps]$ vi pj1/pj1/urls.py
from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),

    # 下記を追加
    url(r'^app1/', include('app1.urls', namespace = 'app1')),
]

接下来,在应用程序目录下创建一个名为ulrs.py的新文件。
在这里,我们将配置以下URL以使其有效。
– http://192.168.33.15:8000/app1/ipaddress/

 (venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/urls.py
from django.conf.urls import patterns, url
from app1 import views

urlpatterns = [
    url(r'^ipaddress/^$', views.index, name='ipaddress_list'),
]

定义视图(Hello Django 编辑)

通过编辑应用程序目录下的views.py文件来定义视图。
首先定义一个最简单的视图,只显示”Hello Django”。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/models.py
from django.http import HttpResponse

def ipaddress(request):
    return HttpResponse("Hello Django")

我会启动一个简易的Web服务器,并通过主机上的Web浏览器进行确认。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py runserver 0.0.0.0:8000
http://192.168.33.15:8000/app1/ipaddress/
django_hello.png

如果只是一个简单的文本展示的Web应用程序,可以按照这样的方式创建,但是对于一些更加丰富的信息的Web应用程序,我们将会利用模板引擎、Bootstrap等CSS框架进行开发。

安装Bootstrap

在未来的Web应用程序中,我们将使用CSS框架Bootstrap。使用Bootstrap,您可以使用最少量的HTML代码创建一个外观整齐的Web页面。

首先下载Bootstrap。

(venv_app1) [vagrant@localhost django_apps]$ sudo wget https://github.com/twbs/bootstrap/releases/download/v3.3.5/bootstrap-3.3.5-dist.zip

(venv_app1) [vagrant@localhost django_apps]$ sudo yum install -y unzip

(venv_app1) [vagrant@localhost django_apps]$ sudo unzip bootstrap-3.3.5-dist.zip

展开正确后,目录结构如下所示。

bootstrap-3.3.5-dist
|-- css
|   |-- bootstrap-theme.css
|   |-- bootstrap-theme.css.map
|   |-- bootstrap-theme.min.css
|   |-- bootstrap.css
|   |-- bootstrap.css.map
|   `-- bootstrap.min.css
|-- fonts
|   |-- glyphicons-halflings-regular.eot
|   |-- glyphicons-halflings-regular.svg
|   |-- glyphicons-halflings-regular.ttf
|   |-- glyphicons-halflings-regular.woff
|   `-- glyphicons-halflings-regular.woff2
`-- js
    |-- bootstrap.js
    |-- bootstrap.min.js
    `-- npm.js

然后,我们要下载一个名为jQuery的JavaScript库,用于在Bootstrap中使用。

(venv_app1) [vagrant@localhost django_apps]$ sudo wget http://code.jquery.com/jquery-2.1.4.min.js

将jQuery文件移动到先前下载的bootstrap的「bootstrap-3.3.5-dist/js/」文件夹中。

(venv_app1) [vagrant@localhost django_apps]$ mv jquery-2.1.4.min.js bootstrap-3.3.5-dist/js/
bootstrap-3.3.5-dist
|-- css
|   |-- bootstrap-theme.css
|   |-- bootstrap-theme.css.map
|   |-- bootstrap-theme.min.css
|   |-- bootstrap.css
|   |-- bootstrap.css.map
|   `-- bootstrap.min.css
|-- fonts
|   |-- glyphicons-halflings-regular.eot
|   |-- glyphicons-halflings-regular.svg
|   |-- glyphicons-halflings-regular.ttf
|   |-- glyphicons-halflings-regular.woff
|   `-- glyphicons-halflings-regular.woff2
`-- js
    |-- bootstrap.js
    |-- bootstrap.min.js
    |-- jquery-2.1.4.min.js
    `-- npm.js

然后,在“pj1/app1”应用程序目录下创建一个新的“static”目录,
并将之前的bootstrap-3.3.5-dist目录下的所有文件移动过来。

(venv_app1) [vagrant@localhost django_apps]$ mkdir pj1/app1/static
(venv_app1) [vagrant@localhost django_apps]$ mv bootstrap-3.3.5-dist/* pj1/app1/static/

最终,目录结构会变成这样。

pj1
|-- app1
|   |-- __init__.py
|   |-- __pycache__
|   |   |-- __init__.cpython-34.pyc
|   |   |-- admin.cpython-34.pyc
|   |   `-- models.cpython-34.pyc
|   |-- admin.py
|   |-- dumpdata
|   |   `-- ap1_db_dump.json
|   |-- migrations
|   |   |-- 0001_initial.py
|   |   |-- __init__.py
|   |   `-- __pycache__
|   |       |-- 0001_initial.cpython-34.pyc
|   |       `-- __init__.cpython-34.pyc
|   |-- models.py
|   |-- static
|   |   |-- css
|   |   |   |-- bootstrap-theme.css
|   |   |   |-- bootstrap-theme.css.map
|   |   |   |-- bootstrap-theme.min.css
|   |   |   |-- bootstrap.css
|   |   |   |-- bootstrap.css.map
|   |   |   `-- bootstrap.min.css
|   |   |-- fonts
|   |   |   |-- glyphicons-halflings-regular.eot
|   |   |   |-- glyphicons-halflings-regular.svg
|   |   |   |-- glyphicons-halflings-regular.ttf
|   |   |   |-- glyphicons-halflings-regular.woff
|   |   |   `-- glyphicons-halflings-regular.woff2
|   |   `-- js
|   |       |-- bootstrap.js
|   |       |-- bootstrap.min.js
|   |       |-- jquery-2.1.4.min.js
|   |       `-- npm.js
|   |-- tests.py
|   |-- urls.py
|   `-- views.py
|-- manage.py
`-- pj1
    |-- __init__.py
    |-- __pycache__
    |   |-- __init__.cpython-34.pyc
    |   |-- settings.cpython-34.pyc
    |   |-- urls.cpython-34.pyc
    |   `-- wsgi.cpython-34.pyc
    |-- settings.py
    |-- urls.py
    `-- wsgi.py

接下来,为了在Django中操作Bootstrap,我们需要安装一个名为django-bootstrap-form的Python包。

(venv_app1) [vagrant@localhost django_apps]$ pip install django-bootstrap-form

(venv_app1) [vagrant@localhost django_apps]$ pip list
Django (1.8.4)
django-bootstrap-form (3.2)
mysqlclient (1.3.6)
pip (7.1.2)
setuptools (12.0.5)
uWSGI (2.0.11.1)

下一步,在pj1/setting.py的INSTALLED_APPS中,添加django-bootstrap-form。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/settings.py


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

    ##以下を追記
    'bootstrapform',

    'app1'
)

创建模板

我们将创建HTML文件模板。在Django中,我们使用Django模板语言(DTL)作为模板引擎,通过将变量嵌入HTML模板来创建Web应用程序。

在DTL中,可以将用{{ }}或{% %}括起来的值作为变量或编程函数来处理。

根据本次IP地址管理应用程序的需求,我们将创建HTML模板。
模板将被放置在“app1/templates/”目录下。

我正在根据Bootstrap入门指南中介绍的以下页面来参考制作。

(venv_app1) [vagrant@localhost django_apps]$ mkdir pj1/app1/templates
(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/templates/ipaddress.html
{% load staticfiles %}

<!-- Adjust  bootstrap  navbar -->
body { padding-top: 40px; }

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>App1</title>

    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
    <link href="{% static 'css/bootstrap-theme.min.css' %}" rel="stylesheet">
    <script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
  </head>

  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">App1</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">IP address</a></li>
            <li><a href="#">Function 2</a></li>
            <li><a href="#">Function 3</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">
        <h1 class="page-header">IP address</h1>
        <table class="table table-striped table-bordered">

            <thead>
                <tr>
                    <td>IP address</td>
                    <td>Status</td>
                    <td>Description</td>
                </tr>
            </thead>
            <tbody>
                {% for ipaddress in ipaddresses %}
                <tr>
                    <td>{{ ipaddress.ipaddress }}</td>
                    <td>{{ ipaddress.status }}</td>
                    <td>{{ ipaddress.description }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>

    </div><!-- /.container -->

  </body>
</html>

定义View(IP地址显示版)

根据创建的模板,我将尝试创建一个应用程序,以显示数据库中IP地址的信息。我会对pj1/app1/views.py进行如下修改。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/models.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import RequestContext
from app1.models import Ipaddress

def ipaddress(request):
    # データベース上のIPアドレス情報を配列型で取得
    ipaddresses = Ipaddress.objects.all().order_by('id')

    return  render_to_response(
        'ipaddress.html', # テンプレート名を指定
        {'ipaddresses' : ipaddresses }, # 取得したIPアドレス情報をテンプレート内の変数に代入
        context_instance=RequestContext(request)
        )

我会建立一个简易的Web服务器,并在主机的Web浏览器上进行确认。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py runserver 0.0.0.0:8000
http://192.168.33.15:8000/app1/ipaddress/
django_app_ipaddresslist.png

通过将模板文件和视图定义结合起来,可以用相对较少的代码来创建Django应用程序。

定义视图(IP地址管理)

下一步作为应用部分,我们将尝试添加一个IP地址信息变更的功能到应用程序中。
我不会详细解释,但会给出修改后的文件。

首先,我们将编辑app1/urls.py文件如下:
在这里,我们定义了新的URL,例如http://192.168.33.15:8000/app1/ipaddress/change/1/,并指定它与数据库中的IP地址信息的主ID关联为”ipaddress_id”。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/urls.py
from django.conf.urls import patterns, url
from app1 import views

urlpatterns = [
    url(r'^ipaddress/$', views.ipaddress, name='ipaddress'),
    url(r'^ipaddress/change/(?P<ipaddress_id>\d+)/$', views.ipaddress_change, name='ipaddress_change'),
]

接下来,我们要创建app1/forms.py文件,以便直接更改ipaddress表的字段信息的值。创建forms.py文件后,我们可以在HTML模板中使用{{ form }}来调用所有字段。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/forms.py
from django.forms import ModelForm
from app1.models import Ipaddress

class IpaddressForm(ModelForm):
    class Meta:
        model = Ipaddress
        fields = ('id', 'ipaddress', 'status', 'description')

接下来,我们要对app1/veiws.py进行以下追加。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/views.py
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from django.shortcuts import render_to_response,  get_object_or_404, redirect
from django.template import RequestContext
from app1.models import Ipaddress
from app1.forms import IpaddressForm

def ipaddress(request):
    ipaddresses = Ipaddress.objects.all().order_by('id')

    return  render_to_response(
        'ipaddress.html',
        {'ipaddresses' : ipaddresses },
        context_instance=RequestContext(request)
        )

def ipaddress_change(request, ipaddress_id=None):

    if ipaddress_id:
        ipaddress =  get_object_or_404(Ipaddress, pk=ipaddress_id)
    else:
        ipaddress = Ipaddress()

    if request.method == 'POST':
        # 基本的にPOSTが推奨される
        form = IpaddressForm(request.POST, instance=ipaddress)
        if form.is_valid():
            form = form.save(commit=False)
            form.save()
            return redirect('app1:ipaddress')
    else:
        # GETの場合はこちらを実行
        form = IpaddressForm(instance=ipaddress)

    return  render_to_response(
        'ipaddress_change.html',
        dict(form=form, ipaddress_id=ipaddress_id),
        context_instance=RequestContext(request)
        )

将模板文件app1/template/ipaddress.html以以下方式追加。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/templates/ipaddress.html
{% load staticfiles %}

<!-- Adjust  bootstrap  navbar -->
body { padding-top: 40px; }

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>App1</title>

    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
    <link href="{% static 'css/bootstrap-theme.min.css' %}" rel="stylesheet">
    <script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
  </head>

  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">App1</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">IP address</a></li>
            <li><a href="#">Function 2</a></li>
            <li><a href="#">Function 3</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">
        <h1 class="page-header">IP address</h1>
        <table class="table table-striped table-bordered">

            <thead>
                <tr>
                    <td>ID</td>
                    <td>IP address</td>
                    <td>Status</td>
                    <td>Description</td>
                    <td>Function</td>
                </tr>
            </thead>
            <tbody>
                {% for ipaddress in ipaddresses %}
                <tr>
                    <td>{{ ipaddress.id }}</td>
                    <td>{{ ipaddress.ipaddress }}</td>
                    <td>{{ ipaddress.status }}</td>
                    <td>{{ ipaddress.description }}</td>
                    <td>
                        <a href="{% url 'app1:ipaddress_change' ipaddress_id=ipaddress.id  %}" class="btn btn-default btn-sm">Change Status</a>
                    </td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div><!-- /.container -->


  </body>
</html>

另外,为了实现变更功能,我们将创建一个新的模板文件app1/template/ipaddress_change.html。前半部分是将app1/template/ipaddress.html的内容复制过来。

(venv_app1) [vagrant@localhost django_apps]$ vi pj1/app1/templates/ipaddress_change.html
{% load staticfiles %}

<!-- Adjust  bootstrap  navbar -->
body { padding-top: 40px; }

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>App1</title>

    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
    <link href="{% static 'css/bootstrap-theme.min.css' %}" rel="stylesheet">
    <script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
  </head>

  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">App1</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">IP address</a></li>
            <li><a href="#">Function 2</a></li>
            <li><a href="#">Function 3</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">
      <h3 class="page-header">Change Status</h3>
      <form action="" method="post" class="form-horizontal" role="form">
          {% csrf_token %}
          {{ form }}
          <div class="form-group">
            <div class="container">
                <button type="submit" class="btn btn-primary">Change Status</button>
                <a href="{% url 'app1:ipaddress' %}" class="btn btn-default btn-sm">Back</a>
            </div>
          </div>
      </form>
    </div><!--/.nav-collapse -->

  </body>
</html>

通过上述的文件编辑,可以创建一个应用程序,使得可以通过点击“更改状态”按钮来修改IP地址信息。

我再次启动了一个简易的Web服务器,并在主机上的Web浏览器中进行确认。

(venv_app1) [vagrant@localhost django_apps]$ python pj1/manage.py runserver 0.0.0.0:8000
http://192.168.33.15:8000/app1/ipaddress/
django_app_ipaddress_change1.png
django_app_ipaddress_change2.png

我已经成功地创建了一个简单的Web应用程序。到目前为止,我们使用了Django提供的简易Web服务器进行了验证。接下来,我将解释如何将应用程序部署到实际的Web服务器(例如Nginx)中。

广告
将在 10 秒后关闭
bannerAds