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):
        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):
        return self.headline

安装

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

$ python manage.py migrate

migrate命令会查看所有可用的模型,并为您的数据库中的表创建不管哪个表已经存在,以及可选地提供丰富的参数控制

享受自由的API

有了这个,你就有了一个自由的,丰富的Python API来访问你的数据。 API即时创建,不需要代码生成:

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

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

# 创建一个新的记者
>>> 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()
<QuerySet [<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()
<QuerySet [<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()
<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就可以自动创建一个专业的,生产就绪的管理界面 - 一个允许经过身份验证的用户添加,更改和删除对象的网站。 它就像在管理站点中注册您的模型一样简单:

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应用的典型工作流程是:先创建模型,接着最先让管理页run起来,这样你的同事或者客户就可以开始往系统里填数据。 然后,开发如何将数据展示给公众的部分。

设计你的URL

简洁优雅的URL模式对于高质量web应用来说,是一个很重要的细节。 Django鼓励漂亮的URL设计,并且不会在URL中添加任何内容,例如.php.asp

要为应用程序设计URL,请创建一个名为URLconf的Python模块。 您的应用程序的目录,它包含URL模式和Python回调函数之间的简单映射。 URLconf还用于将URL与Python代码分离。

以下是上面Reporter / Article示例的URLconf外观:

mysite/news/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>/', views.month_archive),
    path('articles/<int:year>/<int:month>/<int:pk>/', views.article_detail),
]

上面的代码将URL路径映射到Python回调函数(“views”)。 路径字符串使用参数标记来“捕获”URL中的值。 当用户请求页面时,Django按顺序遍历每个路径,并在与请求的URL匹配的第一个路径上停止。 (如果它们都不匹配,Django会调用特殊情况404视图。) 这非常快,因为路径在加载时被编译为正则表达式。

一旦其中一个URL模式匹配,Django就会调用给定的视图,这是一个Python函数。 每个视图都会传递一个请求对象 - 其中包含请求元数据 - 以及模式中捕获的值。

例如,如果用户请求URL“/ articles / 2005/05 / 39323 /”,Django将调用函数news.views.article_detail(request, year = 2005 , 月= 5, pk = 39323)

视图

每个视图负责执行以下两项操作之一:返回包含所请求页面内容的HttpResponse对象,或引发异常,例如Http404 剩下的由你决定。

通常,view根据参数检索数据,加载模板并使用检索到的数据呈现模板。 以下是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风格的“管道”(“|”字符)。 这称为模板过滤器,它是一种过滤变量值的方法。 在这种情况下,日期过滤器以给定格式格式化Python日期时间对象(如PHP的日期函数中所示)。

您可以根据需要将尽可能多的过滤器链接在一起。 您可以编写自定义模板过滤器 您可以编写自定义模板标记(在后台运行自定义Python代码)。

Finally, Django uses the concept of “template inheritance”. That’s what the {% extends "base.html" %} does. It means “First load the template called ‘base’, which has defined a bunch of blocks, and fill the blocks with the following blocks.” In short, that lets you dramatically cut down on redundancy in templates: each template has to define only what’s unique to that template.

Here’s what the “base.html” template, including the use of static files, might look like:

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>

简单地说,它定义了站点的外观(带有站点的标识),并为子模板填充提供了“接口”以便子模板去填充。 这使得站点重新设计和更改单个文件(基本模板)一样简单。

它还允许您使用不同的基本模板创建站点的多个版本,同时重用子模板。 Django的创建者使用这一技术创建了不同的移动版本的站点,只需创建一个新的基本模板。

注意,如果您喜欢其他系统,则不必使用Django的模板系统。 虽然Django的模板系统与Django的模型层集成得特别好,但是没有什么强迫您使用它。 For that matter, you don’t have to use Django’s database API, either. 您可以使用另一个数据库抽象层,可以读取XML文件,可以从磁盘上读取文件,或者任何您想要的东西。 Each piece of Django – models, views, templates – is decoupled from the next.

This is just the surface

This has been only a quick overview of Django’s functionality. Some more useful features:

  • A caching framework that integrates with memcached or other backends.
  • A syndication framework that makes creating RSS and Atom feeds as easy as writing a small Python class.
  • More sexy automatically-generated admin features – this overview barely scratched the surface.

The next obvious steps are for you to download Django, read the tutorial and join the community. Thanks for your interest!