Django 概览 — Django 文档
初识 Django
因为 Django 是在快节奏的新闻编辑室环境中开发的,所以它旨在使常见的 Web 开发任务变得快速而简单。 这是关于如何使用 Django 编写数据库驱动的 Web 应用程序的非正式概述。
本文档的目标是为您提供足够的技术细节以了解 Django 的工作原理,但这不是教程或参考——但我们两者都有! 当您准备好开始一个项目时,您可以 从教程开始 或 直接进入更详细的文档 。
设计模型
尽管您可以在没有数据库的情况下使用 Django,但它带有 对象关系映射器 ,您可以在其中用 Python 代码描述数据库布局。
数据模型语法 提供了许多表示模型的丰富方式——到目前为止,它已经解决了多年的数据库模式问题。 这是一个快速示例:
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 命令行实用程序以自动创建数据库表:
:djadmin:`makemigrations` 命令查看所有可用模型并为不存在的表创建迁移。 :djadmin:`migrate` 运行迁移并在您的数据库中创建表,以及可选地提供 更丰富的模式控制 。
享用便捷的 API
有了它,您就有了一个免费且丰富的 Python API 来访问您的数据。 API 是即时创建的,无需生成代码:
# Import the models we created from our "news" app
>>> from news.models import Article, Reporter
# No reporters are in the system yet.
>>> Reporter.objects.all()
<QuerySet []>
# 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()
<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 可以自动创建一个专业的、生产就绪的 管理界面 ——一个允许经过身份验证的用户添加、更改和删除对象的网站。 就像在管理站点中注册您的模型一样简单:
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)
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 回调函数之间的简单映射。 URLconfs 还用于将 URL 与 Python 代码解耦。
对于上面的 Reporter
/Article
示例,URLconf 可能如下所示:
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 回调函数(“视图”)。 路径字符串使用参数标签从 URL 中“捕获”值。 当用户请求一个页面时,Django 按顺序运行每个路径,并在第一个与请求的 URL 匹配的路径处停止。 (如果它们都不匹配,Django 会调用一个特殊情况的 404 视图。)这非常快,因为路径在加载时被编译成正则表达式。
一旦其中一个 URL 模式匹配,Django 就会调用给定的视图,这是一个 Python 函数。 每个视图都会传递一个请求对象——其中包含请求元数据——以及模式中捕获的值。
例如,如果用户请求 URL“/articles/2005/05/39323/”,Django 将调用函数 news.views.article_detail(request, year=2005, month=5, pk=39323)
。
编写视图
每个视图负责做两件事之一:返回一个包含请求页面内容的 HttpResponse 对象,或者引发一个异常,例如 Http404。 剩下的就看你了。
通常,视图根据参数检索数据,加载模板并使用检索到的数据呈现模板。 这是上面 year_archive
的示例视图:
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 设置中,您指定一个目录列表来检查模板 :setting:`目录 ` . 如果第一个目录中不存在模板,它会检查第二个目录,依此类推。
假设找到了 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
使用 Unix 风格的“管道”(“|”字符)。 这称为模板过滤器,它是一种过滤变量值的方法。 在这种情况下,日期过滤器以给定格式(在 PHP 的日期函数中找到)格式化 Python 日期时间对象。
您可以根据需要将任意数量的过滤器链接在一起。 您可以编写 自定义模板过滤器 。 您可以编写 自定义模板标签 ,它会在幕后运行自定义 Python 代码。
最后,Django 使用了“模板继承”的概念。 这就是 {% extends "base.html" %}
的作用。 它的意思是“首先加载名为‘base’的模板,它定义了一堆块,然后用下面的块填充这些块。” 简而言之,这可以让您显着减少模板中的冗余:每个模板必须仅定义该模板独有的内容。
以下是“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 的模型层集成得特别好,但没有什么会强迫您使用它。 就此而言,您也不必使用 Django 的数据库 API。 您可以使用另一个数据库抽象层,您可以读取 XML 文件,您可以从磁盘读取文件,或者任何您想要的。 Django 的每一部分——模型、视图、模板——都与下一个分离。