Django概览

因为Django是在快节奏的新闻编辑室环境中开发出的,它旨在使常见的Web开发任务变得快速而容易。 以下是如何使用Django编写数据库驱动的Web应用程序的非正式概述。

本文档的目的是为您提供足够的技术细节来了解Django的工作原理,它并不是一个教程或参考 —— 不过这两者我们都有了!当您准备开始一个项目时,可以 从教程开始深入阅读详细的文档

设计您的模型(model)

虽然您在使用Django时可以不用数据库,但它带有一个 对象关系映射器(object-relational mapper), 可以通过Python代码描述数据库布局。

数据模型语法 提供了许多丰富的表示模型的方法 —— 到目前为止,它一直在解决多年来数据库模式问题。 以下是一个简单的例子:

mysite/news/models.py
from django.db import models

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)

    def __str__(self):              # __unicode__ on Python 2
        return self.full_name

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

安装它吧

接下来,运行Django命令行实用程序来自动创建数据库表:

$ python manage.py migrate

migrate 命令用来查看所有可用的模型,并在数据库中创建不存在的表,以及 提供可选的 更丰富的模式控制

享用便捷的API

接着,您就拥有一个便捷而丰富的 Python API 来访问您的数据。 这些API即时创建,无需代码生成:

# 从我们的“新闻”应用中导入我们创建的模型
>>> from news.models import Reporter, Article

# 系统中还没有reporter。
>>> Reporter.objects.all()
<QuerySet []>

# 创建新的Reporter。
>>> r = Reporter(full_name='John Smith')

# 将对象保存到数据库中。 您必须显式调用save()。
>>> r.save()

# 现在它有了一个ID。
>>> r.id
1

# 现在数据库中有了新的reporter。
>>> Reporter.objects.all()
<QuerySet [<Reporter: John Smith>]>

# 字段表示为Python对象中的属性。
>>> r.full_name
'John Smith'

# Django提供了丰富的数据库查找API。
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__startswith='John')
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains='mith')
<Reporter: John Smith>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Reporter matching query does not exist.

# 创建一个article。
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Django is cool',
...     content='Yeah.', reporter=r)
>>> a.save()

# 现在数据库中有个article。
>>> Article.objects.all()
<QuerySet [<Article: Django is cool>]>

# Article对象可以访问相关联的Reporter对象的API。
>>> r = a.reporter
>>> r.full_name
'John Smith'

# 反之亦然:Reporter对象可以访问Article对象的API。
>>> r.article_set.all()
<QuerySet [<Article: Django is cool>]>

# API遵循您所需的关系,为您在幕后执行高效的JOIN。
# 以下查找所有reporter以“John”为名的article。
>>> Article.objects.filter(reporter__full_name__startswith='John')
<QuerySet [<Article: Django is cool>]>

# 通过更改其属性并调用save()来更改对象。
>>> r.full_name = 'Billy Goat'
>>> r.save()

# 用delete()删除一个对象。
>>> r.delete()

一个动态的管理界面:它不只是脚手架 —— 还是完整的房子

一旦定义了模型,Django可以自动创建一个专业的为生产环境准备的 管理界面 —— 允许通过身份验证的用户添加、更改和删除对象的网站。 在管理员网站上注册您的模型非常简单:

mysite/news/models.py
from django.db import models

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
mysite/news/admin.py
from django.contrib import admin

from . import models

admin.site.register(models.Article)

这里的理念是,您的网站由员工或客户编辑,也可能仅由您来编辑 —— 您无需关系创建后端接口 来管理内容。

创建Django应用程序的一个典型工作流程是创建模型并尽可能快地运行管理站点,这样您的员工 (或客户)就可以开始填充数据。 然后,开发将数据呈现给公众的方式。

设计您的URLs

一个干净、优雅的URL方案是高质量Web应用程序中的重要细节。Django鼓励漂亮的URL设计, 不会在URL中放置任何杂乱的内容,比如 .php.asp

要设计应用的URL,您可以创建一个名为 URLconf 的Python模块。 您的应用内容表中,包含了URL模式和Python回调函数之间的简单映射。URLconf还用于将URL与 Python代码分离。

下面有一个 Reporter/Article 的URLconf可能是什么样子的例子:

mysite/news/urls.py
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

上述代码通过简单的 正则表达式 将URL映射到Python回调函数(“views”)。 正则表达式使用括号来在URL中“捕获”值。当用户请求页面时,Django按顺序运行每个模式, 并在停止在与所请求的URL匹配的第一个模式。(如果没有匹配,Django会调用表示特殊情况的404视图。) 此过程非常快,这是因为正则表达式是在加载时就编译好了。

一旦其中一个正则表达式匹配成功,Django会导入并调用给定的视图,即一个简单的Python函数。 每个视图都会传递一个请求对象(包含请求元数据)以及在正则表达式中捕获的值。

例如,如果用户请求URL“/articles/2005/05/39323/”,Django会调用函数 news.views.article_detail(request, '2005', '05', '39323')

编写您的视图(views)

每个视图负责执行以下两项操作之一:返回 HttpResponse 对象, 其中包含请求页面的内容,或者引发如 Http404 的异常。剩下的取决于您。

通常,视图根据参数检索数据,加载模板并使用检索到的数据渲染模板。以下是上述 year_archive 的示例视图:

mysite/news/views.py
from django.shortcuts import render

from .models import Article

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    context = {'year': year, 'article_list': a_list}
    return render(request, 'news/year_archive.html', context)

该示例使用Django的 模板系统,它具有许多强大特性, 但也努力保持足够简单,以让非程序员使用。

设计您的模板(templates)

上述代码加载了 news/year_archive.html 模板。

Django有一个模板搜索路径,它允许您最大限度地减少模板之间的冗余。在您的Django设置中, 您可以使用 DIRS 指定要检查的模板目录列表。如果第一个目录中 不存在模板,则会检查第二个目录,依此类推。

假设发现了 news/year_archive.html 模板,可能会是下面这个样子:

mysite/news/templates/news/year_archive.html
{% extends "base.html" %}

{% block title %}Articles for {{ year }}{% endblock %}

{% block content %}
<h1>Articles for {{ year }}</h1>

{% for article in article_list %}
    <p>{{ article.headline }}</p>
    <p>By {{ article.reporter.full_name }}</p>
    <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}

变量被双花括号包围。{{article.headline}} 表示“输出文章标题属性的值”。但是里面的点 不仅仅用于属性查找。它们还可以进行字典键查找、索引查找和函数调用。

注意 {{ article.pub_date|date:"F j, Y" }} 使用Unix风格的“管道”(“|”)字符。 这被称为模板过滤器,它是一种过滤变量值的方法。在这种情况下,日期过滤器会以给定的格式 格式化Python datetime对象(一如PHP的日期函数)。

您可以将所需的过滤器连接在一起。您可以编写 自定义的模板过滤器,它在幕后运行自定义的Python代码。

最后,Django使用“模板继承”的概念。就是 {% extends "base.html" %} 所做的。 这意味着“首先加载名为‘base’的模板,它定义了一堆块,并使用以下块来填充”。简而言之, 这可以大大减少模板中的冗余:每个模板必须只定义该模板的唯一的内容。

以下是“base.html”模板,也包括 静态文件 的使用, 可能的样子:

mysite/templates/base.html
{% load static %}
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="{% static "images/sitelogo.png" %}" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>

简单地说,它定义了网站的外观(含网站的 logo),并为子模板提供了用来填充的“块”。 这使得重新设计站点变得非常容易,只需改变单个文件(基础模板)。

它还允许您创建多个版本的站点,具有不同的基础模板,同时重用子模板。Django的创作者使用 这种技术创建显著不同的手机版本网站 —— 只需创建一个新的基础模板。

请注意,如果您喜欢其他系统,就不必使用Django的模板系统。Django的模板系统能和Django的 模型层完美结合,但不会强制您使用它。同样,您也不必使用Django的数据库API。 您可以使用其他数据库抽象层,您可以读取XML文件,可以从磁盘读取文件,或任何您想要的内容。 Django的每个组成部分 —— 模型、视图和模板 —— 都与下一个解耦。

这仅仅是一点皮毛

这只是Django功能的简要概述。 一些更有用的特性:

  • 一个 缓存框架 可以与memcached或其他后端缓存集成。
  • 一个 聚合框架 可以让创建RSS和Atom的feeds与 写一个小小的Python类一样容易。
  • 更赞的自动生成管理站点功能 —— 本概述仅是蜻蜓点水。

显然,下一步您应该 下载 Django,阅读 入门教程 并且加入 社区。感谢您的关注!