Ross Wan's World!

Python, Ajax, PHP and Linux.

浅尝Python Web 框架:Django

Posted by Ross Wan 于 2007/08/07

1.介绍

Django 是一个高级 Python web framework,遵守BSD版权,它鼓励快速开发和干净的、MVC 设计,包括一个模板系统,对象相关的映射和用于动态创建管理界面的框架。使用 Django,我们在几分钟之内就可以创建高品质、易维护、数据库驱动的应用程序。

Django 的名字是从一位比利时爵士音乐家来的。这是从 Django 的 FAQ 中看到的。这位音乐家名叫: Django Reinhardt ,他是一个吉普赛人,主要以演奏吉它为主,还演奏过小提琴等。在1930年到1950年初的这段日子里,他被认为是最好的吉它演奏家。根据百科全书的说 明,django的发音为: zhane-go (’a’发长音)

Django 项目是一个定制框架,它源自一个在线新闻 Web 站点,于 2005 年以开源的形式被释放出来。Django 框架的核心组件有:

  • 用于创建模型的对象关系映射
  • 为最终用户设计的完美管理界面
  • 一流的 URL 设计
  • 设计者友好的模板语言
  • 缓存系统


2.安装Django

Django 当前最新的官方版本是0.96。单击这里下载。然后解压,执行以下使命来安装:

tar xzvf Django-0.96.tar.gz
cd Django-0.96
sudo python setup.py install

3.Django 的管理工具

在安装Django 之后,就有一个可用的Django 管理工具:django-admin.py。在终端或者命令行下,输入命令:django-admin.py,会显示如下的帮助信息:

Usage: django-admin.py action [options]
actions:
adminindex [appname …]
Prints the admin-index template snippet for the given app name(s).

createcachetable [tablename]
Creates the table needed to use the SQL cache backend
dbshell
Runs the command-line client for the current DATABASE_ENGINE

….


4.1 创建Django 项目和应用程序

要新建一个Web 项目, 先在命令行的模式下,进入你想建立项目的目录,执行以下命令:django-admin startproject,例如:

~/Python$ django-admin startproject mysite

上面的命令将会在~/Python 下创建mysite 文件夹,其中包含了运行Django 项目的基本配置文件:

__init__.py manage.py settings.py urls.py
现在,在项目上建立一个应用程序(aplication),以职位公告板”jobs” 为例子:

~/Python/mysite$ python manage.py startapp jobs

上面将建立一个应用程序的骨架,jobs 目录如下:

__init__.py models.py views.py
为了使项目知道新的应用程序存在,需要在settings.py 文件中的INSTALLED_APPS 添加一个条目(‘mysite.jobs’):

INSTALLED_APPS = (
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.sites’,
‘mysite.jobs’,
)

4.2 创建一个模型(Model)

Django 提供了自己的对象关系型数据映射组件(object-relational mapper,ORM)库,它可以通过 Python 对象接口支持动态数据库访问。这个 Python 接口非常有用,功能十分强大,但如果需要,也可以灵活地不使用这个接口,而是直接使用 SQL。

ORM 目前提供了对 PostgreSQL、MySQL、SQLite 和 Microsoft® SQL 数据库的支持。

在新建模型之前,需要对settings.py 文件进行数据库的配置。本例以SQLite3 为例:

DATABASE_ENGINE = ’sqlite3′
DATABASE_NAME = ‘~/Sqlite/test.db’ DATABASE_USER = ”
DATABASE_PASSWORD = ”
DATABASE_HOST = ”
DATABASE_PORT = ”

这个职位公告板应用程序有两种类型的对象:Location 和 Job。Location 包含 city、state(可选)和 country 字段。Job 包含 location、title、description 和 publish date 字段。jobs/models.py 文件内容如下:

from django.db import models

# Create your models here.
class Location(models.Model):
    city = models.CharField(maxlength=50)
    state = models.CharField(maxlength=50, null=True, blank=True)
    country = models.CharField(maxlength=50)

    def __str__(self):
        if self.state:
            return "%s, %s, %s" % (self.city, self.state, self.country)
        else:
            return "%s, %s" % (self.city, self.country)
            
class Job(models.Model):
    pub_date = models.DateField()
    job_title = models.CharField(maxlength=50)
    job_description = models.TextField()
    location = models.ForeignKey(Location)

    def __str__(self):
        return "%s (%s)" % (self.job_title, self.location)

  

__str__ 方法是 Python 中的一个特殊类,它返回对象的字符串表示。Django 在 Admin 工具中显示对象时广泛地使用了这个方法。

执行python manage.py sql jobs 可以看到模型在数据库里的模式:

~/Python/mysite$ python manage.py sql jobs BEGIN; CREATE TABLE “jobs_job” ( “id” integer NOT NULL PRIMARY KEY, “pub_date” date NOT NULL, “job_title” varchar(50) NOT NULL, “job_description” text NOT NULL, “location_id” integer NOT NULL ); CREATE TABLE “jobs_location” ( “id” integer NOT NULL PRIMARY KEY, “city” varchar(50) NOT NULL, “state” varchar(50) NULL, “country” varchar(50) NOT NULL ); COMMIT;
运行数据库命令 syncdb 后,将会初始化并安装这个模型:
~/Python/mysite$ python manage.py syncdb

注意syncdb 命令要求我们创建一个超级用户帐号。这是因为 django.contrib.auth 应用程序(提供基本的用户身份验证功能)默认情况下是在 INSTALLED_APPS 设置中提供的。超级用户名和密码用来登录将在下一节介绍的管理工具。记住,这是 Django 的超级用户,而不是系统的超级用户。

4.3 使用带图形界面的Admin 管理工具

Django 的最大卖点之一是其一流的管理界面,为我们的项目提供了很多数据输入工具。实质上,管理工具是也是一个应用程序,不过是Django 内置。与 jobs 应用程序一样,在使用之前也必须进行安装。第一个步骤是将应用程序的模块(django.contrib.admin)添加到 INSTALLED_APPS 设置中。修改 settings.py 的内容如下:

INSTALLED_APPS = (
 ‘django.contrib.auth’,
 ‘django.contrib.contenttypes’,
 ‘django.contrib.sessions’,
 ‘django.contrib.sites’,
 ‘djproject.jobs’,
 ‘django.contrib.admin’,
)

要让该管理工具可以通过 /admin URL 使用必须对URL 进行配置,修改urls.py 的内容如下:

from django.conf.urls.defaults import *

urlpatterns = patterns(”,
 (r’^admin/’, include(’django.contrib.admin.urls’)),)

这个管理应用程序有自己的数据库模型,但也需要进行安装。我们可以再次使用 syncdb 命令来完成这个过程:

~/Python/mysite$ python manage.py syncdb

启动Django 内置的测试服务器:

~/Python/mysite$ python manage.py runserver

Validating models…
0 errors found.

Django version 0.96, using settings ‘mysite.settings’
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

现在可以在浏览器里输入 http://localhost:8000/admin 启动管理工具,并使用前面创建的超级用户帐号进行登录。

要让模型的类可以通过管理工具进行访问,我们需要为其创建一个 Admin 子类。然后可以通过为这个子类添加类属性来定制如何对每个类进行管理。以下是修改后的jobs/models.py 的内容:

from django.db import models

# Create your models here.
class Location(models.Model):
    city = models.CharField(maxlength=50)
    state = models.CharField(maxlength=50, null=True, blank=True)
    country = models.CharField(maxlength=50)

    def __str__(self):
        if self.state:
            return "%s, %s, %s" % (self.city, self.state, self.country)
        else:
            return "%s, %s" % (self.city, self.country)
            
    class Admin:
        list_display = ("city","state","country")

class Job(models.Model):
    pub_date = models.DateField()
    job_title = models.CharField(maxlength=50)
    job_description = models.TextField()
    location = models.ForeignKey(Location)

    def __str__(self):
        return "%s (%s)" % (self.job_title, self.location)

    class Admin:
        list_display = ("job_title","location","pub_date")
        ordering = ["-pub_date"]
        search_fields=("jab_title","job_description")
        list_filter = ("location",)      

现在就可以通过管理界面来创建、更新和删除 Location 和Jobs 记录了。


4.4 配置URL

Django URL 分发系统使用了正则表达式配置模块,它可以将URL 字符串模式映射到特定的views。这个系统允许URL 与底层代码完全脱节,从而实现最大的控制和灵活性。

项目下的urls.py 模块是URL 的默认配置点(也可以通过 settings.py 模块中的ROOT_URLCONF 值重新设置)。URL 配置文件的惟一要求是必须包含一个定义模式 urlpatterns 的对象。

这个职位公告板应用程序会在启动时打开一个索引和一个详细视图,它们可以通过以下的 URL 映射进行访问:

  • /jobs 索引视图:显示最近的 10 个职位
  • /jobs/1 详细视图:显示 ID 为 1 的职位信息

这两个视图(索引视图和详细视图)都是在这个 jobs 应用程序的 views.py 模块中实现的。在项目的 urls.py 文件中实现这种配置看起来如下所示:

from django.conf.urls.defaults import *

urlpatterns = patterns(”,
 (r’^admin/’, include(’django.contrib.admin.urls’)),
 (r’^jobs/$’, ‘mysite.jobs.views.index’),
 (r’^jobs/(?P<job_id>d+)/$’, ‘mysite.jobs.views.detail’),
)

注意<job_id> 部分,这在后面非常重要。

最佳实践是提取出应用程序特有的 URL 模式,并将它们放入应用程序自身中。这样可以取消应用程序与项目的耦合限制,从而更好地实现重用。jobs 使用的应用程序级的 URL 配置文件(jobs/urls.py)如下所示:

from django.conf.urls.defaults import *

urlpatterns = patterns(’mysite.jobs.views’,
 (r’^$’, ‘index’),
 (r’^(?P<job_id>d+)/$’, ‘detail’),
)

注意:由于 view 方法现在都是来自同一个模块,因此第一个参数可以使用这个模块的根名称来指定 djproject.jobs.views,Django 会使用它来查找 index 方法和 detail 方法。

再将项目下的urls.py 更改为以下内容:

from django.conf.urls.defaults import *

urlpatterns = patterns(”,
 (r’^admin/’, include(’django.contrib.admin.urls’)),
 (r’^jobs/’, include(’mysite.jobs.urls’)),
)

4.5 实现视图

视图是一个简单的 Python 方法,它接受一个请求对象,负责实现:

  • 任何业务逻辑(直接或间接)
  • 上下文字典,它包含模板数据
  • 使用一个上下文来表示模板
  • 响应对象,它将所表示的结果返回到这个框架中

在 Django 中,当一个 URL 被请求时,所调用的 Python 方法称为一个视图(view),这个视图所加载并呈现的页面称为模板(template)。由于这个原因,Django 小组将 Django 称为一个 MVT(model-view-template)框架。

下面将获取最近的 10 个职位,并通过一个模板呈现出来,然后返回响应。jobs/views.py 的内容如下:

from django.template import Context, loader
from django.http import HttpResponsefrom jobs.models import Job

def index(request):
 object_list = Job.objects.order_by(’-pub_date’)[:10]
 t = loader.get_template(’jobs/job_list.html’)
 c = Context({
 ‘object_list’: object_list,
 })
 return HttpResponse(t.render(c))

在上面的代码中,模板是由 jobs/job_list.html 字符串进行命名的。该模板是使用名为 object_list 的职位列表的上下文呈现的。所呈现的模板字符串随后被传递到 HTTPResponse 构造器中,后者通过这个框架被发送回请求客户机那里。

加载模板、创建内容以及返回新响应对象的步骤在下面都被 render_to_response 方法取代了。新增内容是详细视图方法使用了一个 get_object_or_404 方法,通过该方法使用所提供的参数获取一个 Job 对象。如果没有找到这个对象,就会触发 404 异常。这两个方法减少了很多 Web 应用程序中的样板代码。修改jobs/views.ps 的内容:

from django.shortcuts import get_object_or_404, render_to_response
from jobs.models import Job

def index(request):
    object_list = Job.objects.order_by('-pub_date')[:10]
    return render_to_response('job_list.html',
                              {'object_list': object_list})

def detail(request, job_id):
    job = get_object_or_404(Job, pk=job_id)
    return render_to_response('job_detail.html',
                              {'object': job})

注意detail 使用 object_id 作为一个参数。这是前面提到过的 jobs/urls.py 文件中 /jobs/ URL 路径后面的数字。它以后会作为参数传递给 get_object_or_404 方法。

4.6 创建模板

Django 提供了一种模板语言,该语言可以快速呈现和易于使用。Django 模板是利用 {{ variables }}{% tags %} 标记嵌入文本来创建的。模板可以用来生成任何基于文本的格式,包括 HTML、XML、CSV 和纯文本。

第一个步骤是定义将模板加载点。为了简便起见,我们需要在mysite 项目 下面创建一个 templates 目录,并将这个路径添加到settings.py 的TEMPLATE_DIRS 条目中:

TEMPLATE_DIRS = (
 ‘~/Python/mysite/templates/’,
)

Django 模板支持模板继承(template inheritance)的概念,它允许设计人员创建一个统一的外表,而不用替换每个模板的内容。我们可以通过使用块标记定义骨干文档或基础文档来使用继承。这些块标记都是使用一些包含内容的页面模板来填充的。这个例子给出了一个包含称为 titleextraheadcontent 的块的 HTML 骨干。templates/base.html 文件的内容如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Company Site: {% block title %}Page{% endblock %}</title>
    {% block extrahead %}{% endblock %}
  </head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>

为了取消应用程序与项目之间的耦合,我们使用了一个中间基本文件templates/jobs/base.html 作为Jobs 应用程序所有页面文件的基础。对于这个例子来说,为了简便起见,我们将应用程序的CSS 放到这个基本文件中。在实际的应用程序中,需要有一个正确配置的Web 服务器,将这个CSS 提取出来,并将其放到Web 服务器所服务的静态文件中。templates/jobs/base.html 文件的内容如下:

{% extends "base/base.html" %}

{% block extrahead %}
    <style>
        body {
            font-style: arial;
        }
        h1 {
            text-align: center;
        }
        .job .title {
            font-size: 120%;
            font-weight: bold;
        }
        .job .posted {
            font-style: italic;
        }
    </style>
{% endblock %}

现在我们要创建视图所加载并呈现的两个页面模板。templates/jobs/job_list.html 模板简单地循环遍历 object_list,它通过索引视图遍历其内容,并显示一个到每条记录的详细页面的链接。templates/jobs/job_list.html 内容如下:

{% extends "base.html" %}

{% block title %}Job List{% endblock %}

{% block content %}
    <h1>Job List</h1>
    <ul>
    {% for job in object_list %}
        <li><a href="{{ job.id }}">{{ job.job_title }}</a></li>
    {% endfor %}
    </ul>
{% endblock %}

templates/jobs/job_detail.html 模板页面会显示一条job 的记录。templates/jobs/job_detail.html 文件内容如下:

{% extends "base.html" %}

{% block title %}Job Detail{% endblock %}

{% block content %}
    <h1>Job Detail</h1>

    <div class="job">
        <div class="title">
            {{ object.job_title }}
            -
            {{ object.location }}
        </div>
        <div class="posted">
            Posted: {{ object.pub_date|date:"d-M-Y" }}
        </div>
        <div class="description">
            {{ object.job_description }}
        </div>
    </div>
{% endblock %}

项目已经基本完成,可以到浏览器里测试下结果。今天就到此告一段落~~

Advertisements

一条回应 to “浅尝Python Web 框架:Django”

  1. $columns[4]

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

 
%d 博主赞过: