初识Django

Django 最初被设计用于具有快速开发需求的新闻类站点,目的是要实现简单快捷的网站开发。 以下内容简要介绍了如何使用 Django 实现一个数据库驱动的 Web 应用。

为了让您充分理解 Django 的工作原理,这份文档为您详细描述了相关的技术细节,不过这并不是一份入门教程或者是参考文档(我们当然也为您准备了这些)。 如果您想要马上开始一个项目,可以从 实例教程 开始入手,或者直接开始阅读 详细的参考文档

设计模型

Django 无需数据库就可以使用,它提供了对象关系映射器(ORM)。通过此技术,你可以使用 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是即时创建的,不需要代码生成:

# 导入我们新建的APP的模型
>>> from news.models import Reporter, Article

# x现在系统内还没有任何记者的信息.
>>> Reporter.objects.all()
<QuerySet []>

#插入一个记者信息
>>> 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对象有 API 来访问相关的 Reporter 对象。
>>> r = a.reporter
>>> r.full_name
'John Smith'

# 反之亦然:Reporter对象获得对Article对象的API访问权限。
>>> r.article_set.all()
<QuerySet [<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')
<QuerySet [<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 就会自动生成一个专业的生产级 administrative interface - 一个可以让已认证用户进行添加、更改和删除对象的 Web 站点。 你只需简单的在 admin 站点上注册你的模型即可。

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 应用的典型流程是:先建立数据模型,然后搭建管理站点,尽可能快的跑起来。那样你的团队(或者客户)就可以向网站里填充数据了。 后面我们会谈到如何展示这些数据。

设计您的网址

对于高质量的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的template system,它具有几个强大的功能,但是仍然努力做到了即使对于非编程人员也能保持足够的简单。

设计你的模板

上面的代码加载了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风格的“管道”(“|”字符)。 这叫做模板过滤器,它是过滤变量值的一种方式。 在本例中,date过滤器格式化Python的datetime对象成给定的格式(正如在PHP中日期函数)。

你可以无限制地串联使用多个过滤器。 你可以编写custom template filters 你可以编写custom template tags,在幕后运行自定义的Python代码。

最后,Django使用“模板继承”的概念。 这就是{% extends "base.html" %}所做的事。 这意味着“首先加载名为”base“的模板,它定义了一堆块,并使用以下块填充块。”简而言之,这样可以大大减少模板中的冗余:每个模板只能定义该模板有什么独特之处

下面是“base.html”模板可能的样子,它使用了static files

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 ),并提供“空洞”让子模板填充。 这使站点的重构变得非常容易,只需改变一个文件 —— base模板。

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

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

这只是表面

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

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

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