Django 1.8.2 文档

Django 概述

因为Django是在快节奏的新闻编辑室环境中开发的,它旨在使常见的Web开发任务变得快速而容易。以下简单介绍了如何用 Django 编写一个数据库驱动的 Web 应用程序。

本文档的目标是给你描述足够的技术细节能让你理解Django是如何工作的,它并不仅仅是一个新手指南或参考目录 – 虽然这些内容我们都涵盖了!当你准备开始一个新项目,你可以从新手指南开始也可以先深入阅读一下详细的文档

设计你的模型

尽管您可以使用没有数据库的Django,但它附带了一个对象关系映射器,您可以在其中以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)

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

安装模块

下一步,运行Django命令行工具来自动创建数据库表:

$ python manage.py migrate

migrate命令会查找你所有可用的模型然后在你的数据库中创建还不存在的数据库表,同时还提供非常丰富的模式控制

使用方便的API

接着,你就可以使用一个便捷且功能丰富的Python API来访问你的数据。这些API是即时创建的,不需要代码生成:

# Import the models we created from our "news" app
>>> from news.models import Reporter, Article

# No reporters are in the system yet.
>>> Reporter.objects.all()
[]

# Create a new Reporter.
>>> r = Reporter(full_name='John Smith')

# Save the object into the database. You have to call save() explicitly.
>>> r.save()

# Now it has an ID.
>>> r.id
1

# Now the new reporter is in the database.
>>> Reporter.objects.all()
[<Reporter: John Smith>]

# Fields are represented as attributes on the Python object.
>>> r.full_name
'John Smith'

# Django provides a rich database lookup 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.

# Create an article.
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Django is cool',
...     content='Yeah.', reporter=r)
>>> a.save()

# Now the article is in the database.
>>> Article.objects.all()
[<Article: Django is cool>]

# Article objects get API access to related Reporter objects.
>>> r = a.reporter
>>> r.full_name
'John Smith'

# And vice versa: Reporter objects get API access to Article objects.
>>> r.article_set.all()
[<Article: Django is cool>]

# The API follows relationships as far as you need, performing efficient
# JOINs for you behind the scenes.
# This finds all articles by a reporter whose name starts with "John".
>>> Article.objects.filter(reporter__full_name__startswith='John')
[<Article: Django is cool>]

# Change an object by altering its attributes and calling save().
>>> r.full_name = 'Billy Goat'
>>> r.save()

# Delete an object with delete().
>>> r.delete()

动态的管理界面:它不只是一个脚手架 ,而是一所完整的房子。

一旦你的模型定义完毕之后,Django能自动创建一个专业的、可以用于生产环境的 管理界面 – 可以让认证的用户添加、修改和删除对象的一个站点。只需简单地在admin site中注册你的模型即可:

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)
mysite/news/admin.py
from django.contrib import admin

from . import models

admin.site.register(models.Article)

这里的设计理念是你的网站由一个员工、客户或者可能是你自己去编辑 —— 而你不想仅仅为了管理内容而去创建后台界面。

创建Django应用的一个典型工作流程是创建模型然后尽快地让admin sites启动和运行起来, 这样您的员工(或客户)能够开始录入数据。 然后,开发向公众展现数据的方式。

设计你的URLs

对于高质量的Web 应用来说,使用简洁、优雅的URL 模式是一个非常值得重视的细节。Django鼓励使用漂亮的URL设计且不会像.php.asp一样把乱七八糟的东西放到URLs里面,.

为了给一个应用设计URLs,你需要创建一个叫做URLconf的Python模块。这其实是你应用的目录,它包含URL模式与Python回调函数间的一个简单映射。 URLconfs 还用作从Python代码中解耦URLs。

下面是针对上面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),
]

上面的代码将URLs映射作为简单的正则表达式映射到Python的回调函数(视图)。正则表达式通过圆括号来“捕获”URLs中的值。 当一个用户请求一个页面时,Django将按照顺序去匹配每一个模式,并停在第一个匹配请求的URL上。 (如果没有匹配到, Django将调用一个特殊的404视图。)整个过程是极快的,因为正则表达式在加载时就已经编译好了。

一旦有一个正则表达式匹配上了,Django 将导入和调用对应的视图,它其实就是一个简单的Python函数。 每个视图将得到一个request对象 —— 它包含了request 的metadata(元数据) —— 和正则表达式所捕获到的值。

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

编写视图

每个视图只负责两件事中的一件:返回一个包含请求的页面内容的 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的模板系统,它具有几个强大的功能,但是仍然努力做到了即使对于非编程人员也能保持足够的简单。

设计模板

上面的代码加载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的headline属性”。但是点符号不仅用于属性查找。它们还用于字典的键值查找、索引查找和函数调用。

注意{{ article.pub_date|date:"F j, Y" }}使用Unix风格的“管道”(“|”字符)。这叫做模板过滤器,它是过滤变量值的一种方式。 在本例中,date过滤器格式化Python的datetime对象成给定的格式(正如在PHP中日期函数)。

你可以无限制地串联使用多个过滤器。 你可以编写自定义的目标过滤器你可以编写自定义的模板标签,在幕后运行自定义的Python代码。

最后,Django使用“模板继承”的概念。这就是{% extends "base.html" %}所做的事。它表示“首先载入‘base’ 模板,该模板中定义了一系列block,然后使用接下来的(存在于继承模板)blocks填充这些blocks”。简而言之,模板继承让你大大减少模板间的冗余内容:每个模板只需要定义它独特的部分。

下面是“base.html”模板可能的样子,它使用了静态文件

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

简单地说,它定义网站的外观(使用网站的logo ),并提供“空洞”让子模板填充。这使站点的重构变得非常容易,只需改变一个文件 —— base模板。

它还可以让你利用不同的基础模板并重用子模板创建一个网站的多个版本。Django 的创建者已经利用这一技术来创造了显著不同的手机版本的网站 —— 只需创建一个新的基础模板。

请注意,如果你喜欢其它模板系统,你可以不使用Django的模板系统。  虽然Django的模板系统与Django的模型层集成得特别好,但并没有强制你使用它。同理,你也可以不使用Django的数据库API。 你可以使用任何你想要的方法去操作数据,包括其它数据库抽象层,读取 XML 文件或者直接从磁盘中读取文件。Django的每个组成部分 —— 模型、视图和模板都可以解耦。

以上只是个开始

这里只是Django功能的一个快速概览。 以下是一些更有用的功能:

  • 缓存框架可以与memcached或其它后端集成。
  • 聚合框架可以让创建RSS和Atom的 feeds 同写一个小小的 Python 类一样容易。
  • 更加吸引人的是其自动创建的站点管理功能 —— 本文仅仅触及了点皮毛。

很明显,下一步你应该做的是下载Django、阅读教程并加入社区感谢您的关注!