“Django/docs/2.2.x/intro/overview”的版本间差异

来自菜鸟教程
Django/docs/2.2.x/intro/overview
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:Django 概览 — Django 文档}}
 
<div id="django-at-a-glance" class="section">
 
<div id="django-at-a-glance" class="section">
  
 
= 初识 Django =
 
= 初识 Django =
  
Django 最初被设计用于具有快速开发需求的新闻类站点,目的是要实现简单快捷的网站开发。以下内容简要介绍了如何使用 Django 实现一个数据库驱动的 Web 应用。
+
因为 Django 是在快节奏的新闻编辑室环境中开发的,所以它旨在使常见的 Web 开发任务变得快速而简单。 这是关于如何使用 Django 编写数据库驱动的 Web 应用程序的非正式概述。
  
为了让您充分理解 Django 的工作原理,这份文档为您详细描述了相关的技术细节,不过这并不是一份入门教程或者是参考文档(我们当然也为您准备了这些)。如果您想要马上开始一个项目,可以从 [[../tutorial01|<span class="doc">实例教程</span>]] 开始入手,或者直接开始阅读详细的 [[../../topics/index|<span class="doc">参考文档</span>]] 。
+
本文档的目标是为您提供足够的技术细节以了解 Django 的工作原理,但这不是教程或参考——但我们两者都有! 当您准备好开始一个项目时,您可以 [[../tutorial01|从教程开始]] [[../../topics/index|直接进入更详细的文档]] 。
  
 
<div id="design-your-model" class="section">
 
<div id="design-your-model" class="section">
第11行: 第12行:
 
== 设计模型 ==
 
== 设计模型 ==
  
Django 无需数据库就可以使用,它提供了 [https://en.wikipedia.org/wiki/Object-relational_mapping 对象关系映射器] 通过此技术,你可以使用 Python 代码来描述数据库结构。
+
尽管您可以在没有数据库的情况下使用 Django,但它带有 [https://en.wikipedia.org/wiki/Object-relational_mapping 对象关系映射器] ,您可以在其中用 Python 代码描述数据库布局。
  
你可以使用强大的 [[../../topics/db/models|<span class="doc">数据-模型语句</span>]] 来描述你的数据模型,这解决了数年以来在数据库模式中的难题。以下是一个简明的例子:
+
[[../../topics/db/models|数据模型语法]] 提供了许多表示模型的丰富方式——到目前为止,它已经解决了多年的数据库模式问题。 这是一个快速示例:
  
<div id="id1" class="literal-block-wrapper docutils container">
+
<div id="id7" class="literal-block-wrapper docutils container">
  
 
<div class="code-block-caption">
 
<div class="code-block-caption">
第26行: 第27行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
  
 
class Reporter(models.Model):
 
class Reporter(models.Model):
第41行: 第42行:
  
 
     def __str__(self):
 
     def __str__(self):
         return self.headline</pre>
+
         return self.headline</syntaxhighlight>
  
 
</div>
 
</div>
第54行: 第55行:
 
== 应用数据模型 ==
 
== 应用数据模型 ==
  
接下来,运行Django命令行实用程序以自动创建数据库表:
+
接下来,运行 Django 命令行实用程序以自动创建数据库表:
 
 
<div class="highlight-console notranslate">
 
  
<div class="highlight">
+
[[#id1|:djadmin:`makemigrations`]] 命令查看所有可用模型并为不存在的表创建迁移。 [[#id3|:djadmin:`migrate`]] 运行迁移并在您的数据库中创建表,以及可选地提供 [[../../topics/migrations|更丰富的模式控制]] 。
 
 
<pre>$ python manage.py makemigrations
 
$ python manage.py migrate</pre>
 
 
 
</div>
 
 
 
</div>
 
[[../../ref/django-admin#django-admin-makemigrations|<code>makemigrations</code>]] 命令查找所有可用的models,为任意一个在数据库中不存在对应数据表的model创建 migrations 脚本文件。[[../../ref/django-admin#django-admin-migrate|<code>migrate</code>]] 命令则运行这些 migrations 自动创建数据库表。还提供可选的 [[../../topics/migrations|<span class="doc">更丰富的控制模式</span>]]。
 
  
  
第74行: 第65行:
 
== 享用便捷的 API ==
 
== 享用便捷的 API ==
  
接下来,你就可以使用一套便捷而丰富的 [[../../topics/db/queries|<span class="doc">Python API</span>]] 访问你的数据。这些 API 是即时创建的,而不用显式的生成代码:
+
有了它,您就有了一个免费且丰富的 [[../../topics/db/queries|Python API]] 来访问您的数据。 API 是即时创建的,无需生成代码:
  
 
<div class="highlight-python notranslate">
 
<div class="highlight-python notranslate">
第80行: 第71行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre># Import the models we created from our &quot;news&quot; app
+
<syntaxhighlight lang="python"># Import the models we created from our "news" app
&gt;&gt;&gt; from news.models import Article, Reporter
+
>>> from news.models import Article, Reporter
  
 
# No reporters are in the system yet.
 
# No reporters are in the system yet.
&gt;&gt;&gt; Reporter.objects.all()
+
>>> Reporter.objects.all()
&lt;QuerySet []&gt;
+
<QuerySet []>
  
 
# Create a new Reporter.
 
# Create a new Reporter.
&gt;&gt;&gt; r = Reporter(full_name='John Smith')
+
>>> r = Reporter(full_name='John Smith')
  
 
# Save the object into the database. You have to call save() explicitly.
 
# Save the object into the database. You have to call save() explicitly.
&gt;&gt;&gt; r.save()
+
>>> r.save()
  
 
# Now it has an ID.
 
# Now it has an ID.
&gt;&gt;&gt; r.id
+
>>> r.id
 
1
 
1
  
 
# Now the new reporter is in the database.
 
# Now the new reporter is in the database.
&gt;&gt;&gt; Reporter.objects.all()
+
>>> Reporter.objects.all()
&lt;QuerySet [&lt;Reporter: John Smith&gt;]&gt;
+
<QuerySet [<Reporter: John Smith>]>
  
 
# Fields are represented as attributes on the Python object.
 
# Fields are represented as attributes on the Python object.
&gt;&gt;&gt; r.full_name
+
>>> r.full_name
 
'John Smith'
 
'John Smith'
  
 
# Django provides a rich database lookup API.
 
# Django provides a rich database lookup API.
&gt;&gt;&gt; Reporter.objects.get(id=1)
+
>>> Reporter.objects.get(id=1)
&lt;Reporter: John Smith&gt;
+
<Reporter: John Smith>
&gt;&gt;&gt; Reporter.objects.get(full_name__startswith='John')
+
>>> Reporter.objects.get(full_name__startswith='John')
&lt;Reporter: John Smith&gt;
+
<Reporter: John Smith>
&gt;&gt;&gt; Reporter.objects.get(full_name__contains='mith')
+
>>> Reporter.objects.get(full_name__contains='mith')
&lt;Reporter: John Smith&gt;
+
<Reporter: John Smith>
&gt;&gt;&gt; Reporter.objects.get(id=2)
+
>>> Reporter.objects.get(id=2)
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
     ...
 
     ...
第118行: 第109行:
  
 
# Create an article.
 
# Create an article.
&gt;&gt;&gt; from datetime import date
+
>>> from datetime import date
&gt;&gt;&gt; a = Article(pub_date=date.today(), headline='Django is cool',
+
>>> a = Article(pub_date=date.today(), headline='Django is cool',
 
...    content='Yeah.', reporter=r)
 
...    content='Yeah.', reporter=r)
&gt;&gt;&gt; a.save()
+
>>> a.save()
  
 
# Now the article is in the database.
 
# Now the article is in the database.
&gt;&gt;&gt; Article.objects.all()
+
>>> Article.objects.all()
&lt;QuerySet [&lt;Article: Django is cool&gt;]&gt;
+
<QuerySet [<Article: Django is cool>]>
  
 
# Article objects get API access to related Reporter objects.
 
# Article objects get API access to related Reporter objects.
&gt;&gt;&gt; r = a.reporter
+
>>> r = a.reporter
&gt;&gt;&gt; r.full_name
+
>>> r.full_name
 
'John Smith'
 
'John Smith'
  
 
# And vice versa: Reporter objects get API access to Article objects.
 
# And vice versa: Reporter objects get API access to Article objects.
&gt;&gt;&gt; r.article_set.all()
+
>>> r.article_set.all()
&lt;QuerySet [&lt;Article: Django is cool&gt;]&gt;
+
<QuerySet [<Article: Django is cool>]>
  
 
# The API follows relationships as far as you need, performing efficient
 
# The API follows relationships as far as you need, performing efficient
 
# JOINs for you behind the scenes.
 
# JOINs for you behind the scenes.
# This finds all articles by a reporter whose name starts with &quot;John&quot;.
+
# This finds all articles by a reporter whose name starts with "John".
&gt;&gt;&gt; Article.objects.filter(reporter__full_name__startswith='John')
+
>>> Article.objects.filter(reporter__full_name__startswith='John')
&lt;QuerySet [&lt;Article: Django is cool&gt;]&gt;
+
<QuerySet [<Article: Django is cool>]>
  
 
# Change an object by altering its attributes and calling save().
 
# Change an object by altering its attributes and calling save().
&gt;&gt;&gt; r.full_name = 'Billy Goat'
+
>>> r.full_name = 'Billy Goat'
&gt;&gt;&gt; r.save()
+
>>> r.save()
  
 
# Delete an object with delete().
 
# Delete an object with delete().
&gt;&gt;&gt; r.delete()</pre>
+
>>> r.delete()</syntaxhighlight>
  
 
</div>
 
</div>
第156行: 第147行:
 
<div id="a-dynamic-admin-interface-it-s-not-just-scaffolding-it-s-the-whole-house" class="section">
 
<div id="a-dynamic-admin-interface-it-s-not-just-scaffolding-it-s-the-whole-house" class="section">
  
== 一个动态管理接口:并非徒有其表 ==
+
== 动态管理界面:它不仅仅是脚手架——它是整个房子 ==
  
当你的模型完成定义,Django 就会自动生成一个专业的生产级 [[../../ref/contrib/admin/index|<span class="doc">管理接口</span>]] ——一个允许认证用户添加、更改和删除对象的 Web 站点。你只需简单的在 admin 站点上注册你的模型即可:
+
一旦你的模型被定义,Django 可以自动创建一个专业的、生产就绪的 [[../../ref/contrib/admin/index|管理界面]] ——一个允许经过身份验证的用户添加、更改和删除对象的网站。 就像在管理站点中注册您的模型一样简单:
  
<div id="id2" class="literal-block-wrapper docutils container">
+
<div id="id8" class="literal-block-wrapper docutils container">
  
 
<div class="code-block-caption">
 
<div class="code-block-caption">
第171行: 第162行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
  
 
class Article(models.Model):
 
class Article(models.Model):
第177行: 第168行:
 
     headline = models.CharField(max_length=200)
 
     headline = models.CharField(max_length=200)
 
     content = models.TextField()
 
     content = models.TextField()
     reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)</pre>
+
     reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)</syntaxhighlight>
  
 
</div>
 
</div>
第184行: 第175行:
  
 
</div>
 
</div>
<div id="id3" class="literal-block-wrapper docutils container">
+
<div id="id9" class="literal-block-wrapper docutils container">
  
 
<div class="code-block-caption">
 
<div class="code-block-caption">
第195行: 第186行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.contrib import admin
+
<syntaxhighlight lang="python">from django.contrib import admin
  
 
from . import models
 
from . import models
  
admin.site.register(models.Article)</pre>
+
admin.site.register(models.Article)</syntaxhighlight>
  
 
</div>
 
</div>
第206行: 第197行:
  
 
</div>
 
</div>
这样设计所遵循的理念是,站点编辑人员可以是你的员工、你的客户、或者就是你自己——而你大概不会乐意去废半天劲创建一个只有内容管理功能的后台管理界面。
+
这里的理念是,您的网站由员工、客户或可能只有您自己编辑 - 您不想为了管理内容而创建后端界面。
  
创建 Django 应用的典型流程是,先建立数据模型,然后搭建管理站点,之后你的员工(或者客户)就可以向网站里填充数据了。后面我们会谈到如何展示这些数据。
+
创建 Django 应用程序的一个典型工作流程是创建模型并尽快启动和运行管理站点,以便您的员工(或客户)可以开始填充数据。 然后,开发向公众展示数据的方式。
  
  
第216行: 第207行:
 
== 规划 URLs ==
 
== 规划 URLs ==
  
简洁优雅的 URL 规划对于一个高质量 Web 应用来说至关重要。Django 推崇优美的 URL 设计,所以不要把诸如 <code>.php</code> <code>.asp</code> 之类的冗余的后缀放到 URL 里。
+
干净、优雅的 URL 方案是高质量 Web 应用程序中的一个重要细节。 Django 鼓励漂亮的 URL 设计,并且不会在 URL 中放置任何多余的东西,例如 <code>.php</code> <code>.asp</code>
  
为了设计你自己的 [[../../topics/http/urls|<span class="doc">URLconf</span>]] ,你需要创建一个叫做 URLconf 的 Python 模块。这是网站的目录,它包含了一张 URL Python 回调函数之间的映射表。URLconf 也有利于将 Python 代码与 URL 进行解耦(译注:使各个模块分离,独立)。
+
要为应用程序设计 URL,您需要创建一个名为 [[../../topics/http/urls|URLconf]] 的 Python 模块。 您的应用程序的目录,它包含 URL 模式和 Python 回调函数之间的简单映射。 URLconfs 还用于将 URL 与 Python 代码解耦。
  
下面这个 URLconf 适用于前面 <code>Reporter</code>/<code>Article</code> 的例子:
+
对于上面的 <code>Reporter</code>/<code>Article</code> 示例,URLconf 可能如下所示:
  
<div id="id4" class="literal-block-wrapper docutils container">
+
<div id="id10" class="literal-block-wrapper docutils container">
  
 
<div class="code-block-caption">
 
<div class="code-block-caption">
第233行: 第224行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.urls import path
+
<syntaxhighlight lang="python">from django.urls import path
  
 
from . import views
 
from . import views
  
 
urlpatterns = [
 
urlpatterns = [
     path('articles/&lt;int:year&gt;/', views.year_archive),
+
     path('articles/<int:year>/', views.year_archive),
     path('articles/&lt;int:year&gt;/&lt;int:month&gt;/', views.month_archive),
+
     path('articles/<int:year>/<int:month>/', views.month_archive),
     path('articles/&lt;int:year&gt;/&lt;int:month&gt;/&lt;int:pk&gt;/', views.article_detail),
+
     path('articles/<int:year>/<int:month>/<int:pk>/', views.article_detail),
]</pre>
+
]</syntaxhighlight>
  
 
</div>
 
</div>
第248行: 第239行:
  
 
</div>
 
</div>
上述代码将 URL 路径映射到了 Python 回调函数(“视图”)。路径字符串使用参数标签从URL中“捕获”相应值。当用户请求页面时,Django 依次遍历路径,直至初次匹配到了请求的 URL。(如果无匹配项,Django 会调用 404 视图。) 这个过程非常快,因为路径在加载时就编译成了正则表达式。
+
上面的代码将 URL 路径映射到 Python 回调函数(“视图”)。 路径字符串使用参数标签从 URL 中“捕获”值。 当用户请求一个页面时,Django 按顺序运行每个路径,并在第一个与请求的 URL 匹配的路径处停止。 (如果它们都不匹配,Django 会调用一个特殊情况的 404 视图。)这非常快,因为路径在加载时被编译成正则表达式。
  
一旦有 URL 路径匹配成功,Django 会调用相应的视图函数。每个视图函数会接受一个请求对象——包含请求元信息——以及在匹配式中获取的参数值。
+
一旦其中一个 URL 模式匹配,Django 就会调用给定的视图,这是一个 Python 函数。 每个视图都会传递一个请求对象——其中包含请求元数据——以及模式中捕获的值。
  
例如,当用户请求了这样的 URL &quot;/articles/2005/05/39323/&quot;,Django 会调用 <code>news.views.article_detail(request, year=2005, month=5, pk=39323)</code>。
+
例如,如果用户请求 URL“/articles/2005/05/39323/”,Django 将调用函数 <code>news.views.article_detail(request, year=2005, month=5, pk=39323)</code>。
  
  
第260行: 第251行:
 
== 编写视图 ==
 
== 编写视图 ==
  
视图函数的执行结果只可能有两种:返回一个包含请求页面元素的 [[../../ref/request-response#django.http|<code>HttpResponse</code>]] 对象,或者是抛出 [[../../topics/http/views#django.http|<code>Http404</code>]] 这类异常。至于执行过程中的其它的动作则由你决定。
+
每个视图负责做两件事之一:返回一个包含请求页面内容的 [[../../ref/request-response#django.http|HttpResponse]] 对象,或者引发一个异常,例如 [[../../topics/http/views#django.http|Http404]]。 剩下的就看你了。
  
通常来说,一个视图的工作就是:从参数获取数据,装载一个模板,然后将根据获取的数据对模板进行渲染。下面是一个 <code>year_archive</code> 的视图样例:
+
通常,视图根据参数检索数据,加载模板并使用检索到的数据呈现模板。 这是上面 <code>year_archive</code> 的示例视图:
  
<div id="id5" class="literal-block-wrapper docutils container">
+
<div id="id11" class="literal-block-wrapper docutils container">
  
 
<div class="code-block-caption">
 
<div class="code-block-caption">
第275行: 第266行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.shortcuts import render
+
<syntaxhighlight lang="python">from django.shortcuts import render
  
 
from .models import Article
 
from .models import Article
第282行: 第273行:
 
     a_list = Article.objects.filter(pub_date__year=year)
 
     a_list = Article.objects.filter(pub_date__year=year)
 
     context = {'year': year, 'article_list': a_list}
 
     context = {'year': year, 'article_list': a_list}
     return render(request, 'news/year_archive.html', context)</pre>
+
     return render(request, 'news/year_archive.html', context)</syntaxhighlight>
  
 
</div>
 
</div>
第289行: 第280行:
  
 
</div>
 
</div>
这个例子使用了 Django [[../../topics/templates|<span class="doc">模板系统</span>]] ,它有着很多强大的功能,而且使用起来足够简单,即使不是程序员也可轻松使用。
+
这个例子使用了 Django [[../../topics/templates|模板系统]] ,它有几个强大的功能,但力求保持足够简单,让非程序员也能使用。
  
  
第299行: 第290行:
 
上面的代码加载了 <code>news/year_archive.html</code> 模板。
 
上面的代码加载了 <code>news/year_archive.html</code> 模板。
  
Django 允许设置搜索模板路径,这样可以最小化模板之间的冗余。在 Django 设置中,你可以通过 [[../../ref/settings#std-setting-TEMPLATES-DIRS|<code>DIRS</code>]] 参数指定一个路径列表用于检索模板。如果第一个路径中不包含任何模板,就继续检查第二个,以此类推。
+
Django 有一个模板搜索路径,它允许您最大限度地减少模板之间的冗余。 在您的 Django 设置中,您指定一个目录列表来检查模板 [[#id5|:setting:`目录 `]] . 如果第一个目录中不存在模板,它会检查第二个目录,依此类推。
  
让我们假设 <code>news/year_archive.html</code> 模板已经找到。它看起来可能是下面这个样子:
+
假设找到了 <code>news/year_archive.html</code> 模板。 这可能是这样的:
  
<div id="id6" class="literal-block-wrapper docutils container">
+
<div id="id12" class="literal-block-wrapper docutils container">
  
 
<div class="code-block-caption">
 
<div class="code-block-caption">
第314行: 第305行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>{% extends &quot;base.html&quot; %}
+
<syntaxhighlight lang="html+django">{% extends "base.html" %}
  
 
{% block title %}Articles for {{ year }}{% endblock %}
 
{% block title %}Articles for {{ year }}{% endblock %}
  
 
{% block content %}
 
{% block content %}
&lt;h1&gt;Articles for {{ year }}&lt;/h1&gt;
+
<h1>Articles for {{ year }}</h1>
  
 
{% for article in article_list %}
 
{% for article in article_list %}
     &lt;p&gt;{{ article.headline }}&lt;/p&gt;
+
     <p>{{ article.headline }}</p>
     &lt;p&gt;By {{ article.reporter.full_name }}&lt;/p&gt;
+
     <p>By {{ article.reporter.full_name }}</p>
     &lt;p&gt;Published {{ article.pub_date|date:&quot;F j, Y&quot; }}&lt;/p&gt;
+
     <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
 
{% endfor %}
 
{% endfor %}
{% endblock %}</pre>
+
{% endblock %}</syntaxhighlight>
  
 
</div>
 
</div>
第333行: 第324行:
  
 
</div>
 
</div>
我们看到变量都被双大括号括起来了。 <code>{{ article.headline }}</code> 的意思是“输出 article 的 headline 属性值”。这个“点”还有更多的用途,比如查找字典键值、查找索引和函数调用。
+
变量被双花括号包围。 <code>{{ article.headline }}</code>的意思是“输出文章标题属性的值”。 但是点不仅仅用于属性查找。 它们还可以进行字典键查找、索引查找和函数调用。
  
我们注意到 <code>{{ article.pub_date|date:&quot;F j, Y&quot; }}</code> 使用了 Unix 风格的“管道符”(“|”字符)。这是一个模板过滤器,用于过滤变量值。在这里过滤器将一个 Python datetime 对象转化为指定的格式(就像 PHP 中的日期函数那样)。
+
注意 <code>{{ article.pub_date|date:&quot;F j, Y&quot; }}</code> 使用 Unix 风格的“管道”(“|”字符)。 这称为模板过滤器,它是一种过滤变量值的方法。 在这种情况下,日期过滤器以给定格式(在 PHP 的日期函数中找到)格式化 Python 日期时间对象。
  
你可以将多个过滤器连在一起使用。你还可以使用你 [[../../howto/custom-template-tags#howto-writing-custom-template-filters|<span class="std std-ref">自定义的模板过滤器</span>]] 。你甚至可以自己编写 [[../../howto/custom-template-tags|<span class="doc">自定义的模板标签</span>]] ,相关的 Python 代码会在使用标签时在后台运行。
+
您可以根据需要将任意数量的过滤器链接在一起。 您可以编写 [[../../howto/custom-template-tags#howto-writing-custom-template-filters|自定义模板过滤器]] 。 您可以编写 [[../../howto/custom-template-tags|自定义模板标签]] ,它会在幕后运行自定义 Python 代码。
  
Django 使用了 ''模板继承'' 的概念。这就是 <code>{% extends &quot;base.html&quot; %}</code> 的作用。它的含义是''先加载名为 base 的模板,并且用下面的标记块对模板中定义的标记块进行填充''。简而言之,模板继承可以使模板间的冗余内容最小化:每个模板只需包含与其它文档有区别的内容。
+
最后,Django 使用了“模板继承”的概念。 这就是 <code>{% extends &quot;base.html&quot; %}</code> 的作用。 它的意思是“首先加载名为‘base’的模板,它定义了一堆块,然后用下面的块填充这些块。” 简而言之,这可以让您显着减少模板中的冗余:每个模板必须仅定义该模板独有的内容。
  
下面是 base.html 可能的样子,它使用了 [[../../howto/static-files/index|<span class="doc">静态文件</span>]]
+
以下是“base.html”模板,包括使用 [[../../howto/static-files/index|静态文件]] ,可能如下所示:
  
<div id="id7" class="literal-block-wrapper docutils container">
+
<div id="id13" class="literal-block-wrapper docutils container">
  
 
<div class="code-block-caption">
 
<div class="code-block-caption">
第354行: 第345行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>{% load static %}
+
<syntaxhighlight lang="html+django">{% load static %}
&lt;html&gt;
+
<html>
&lt;head&gt;
+
<head>
     &lt;title&gt;{% block title %}{% endblock %}&lt;/title&gt;
+
     <title>{% block title %}{% endblock %}</title>
&lt;/head&gt;
+
</head>
&lt;body&gt;
+
<body>
     &lt;img src=&quot;{% static &quot;images/sitelogo.png&quot; %}&quot; alt=&quot;Logo&quot;&gt;
+
     <img src="{% static "images/sitelogo.png" %}" alt="Logo">
 
     {% block content %}{% endblock %}
 
     {% block content %}{% endblock %}
&lt;/body&gt;
+
</body>
&lt;/html&gt;</pre>
+
</html></syntaxhighlight>
  
 
</div>
 
</div>
第370行: 第361行:
  
 
</div>
 
</div>
简而言之,它定义了这个网站的外观(利用网站的 logo),并且给子模板们挖好了可以填的”坑“。这也让网站的改版变得简单无比——你只需更改这个根模板文件即可。
+
简单地说,它定义了站点的外观(带有站点的徽标),并为子模板提供了要填充的“漏洞”。 这使得站点重新设计就像更改单个文件(基本模板)一样简单。
  
它还可以让你利用不同的基础模板并重用子模板创建一个网站的多个版本。Django 的创建者已经利用这一技术来创造了明显不同的手机版本的网站——只需创建一个新的基础模板。
+
它还允许您使用不同的基本模板创建站点的多个版本,同时重用子模板。 Django 的创建者使用这种技术创建了截然不同的移动版本网站——只需创建一个新的基本模板。
  
注意,你并不是非得使用 Django 的模板系统,你可以使用其它你喜欢的模板系统。尽管 Django 的模板系统与其模型层能够集成得很好,但这不意味着你必须使用它。同样,你可以不使用 Django 的数据库 API。你可以用其他的数据库抽象层,像是直接读取 XML 文件,亦或直接读取磁盘文件,你可以使用任何方式。Django 的任何组成——模型、视图和模板——都是独立的。
+
请注意,如果您更喜欢其他系统,则不必使用 Django 的模板系统。 虽然 Django 的模板系统与 Django 的模型层集成得特别好,但没有什么会强迫您使用它。 就此而言,您也不必使用 Django 的数据库 API。 您可以使用另一个数据库抽象层,您可以读取 XML 文件,您可以从磁盘读取文件,或者任何您想要的。 Django 的每一部分——模型、视图、模板——都与下一个分离。
  
  
第382行: 第373行:
 
== 这仅是基本入门知识 ==
 
== 这仅是基本入门知识 ==
  
以上只是 Django 的功能性概述。Django 还有更多实用的特性:
+
这只是对 Django 功能的快速概览。 一些更有用的功能:
 +
 
 +
* 与 memcached 或其他后端集成的 [[../../topics/cache|缓存框架]] 。
 +
* 一个 [[../../ref/contrib/syndication|联合框架]] ,它使创建 RSS 和 Atom 提要就像编写一个小的 Python 类一样简单。
 +
* 更有吸引力的自动生成的管理功能——这个概述几乎没有触及表面。
  
* [[../../topics/cache|<span class="doc">缓存框架</span>]] 可以与 memcached 或其它后端集成。
+
接下来的明显步骤是[https://www.djangoproject.com/download/ 下载Django],阅读[[../tutorial01|教程]]并加入[https://www.djangoproject.com/community/ 社区]。 谢谢你的关注!
* [[../../ref/contrib/syndication|<span class="doc">聚合器框架</span>]] 可以通过简单编写一个 Python 类来推送 RRS 和 Atom。
 
* 功能丰富的自动生成的后台——这份概要只是简单介绍了下。
 
  
接下来您可以 [https://www.djangoproject.com/download/ 下载 Django] ,阅读 [[../tutorial01|<span class="doc">实例教程</span>]] ,然后加入我们的 [https://www.djangoproject.com/community/ 社区] !感谢您的关注!
 
  
 +
</div>
  
 
</div>
 
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Django 2.2.x 中文文档]]
+
[[Category:Django 2.2.x 文档]]

2021年10月31日 (日) 04:04的最新版本

初识 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 命令行实用程序以自动创建数据库表:

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

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 回调函数之间的简单映射。 URLconfs 还用于将 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 回调函数(“视图”)。 路径字符串使用参数标签从 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 的示例视图:

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 设置中,您指定一个目录列表来检查模板 :setting:`目录 ` . 如果第一个目录中不存在模板,它会检查第二个目录,依此类推。

假设找到了 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 使用 Unix 风格的“管道”(“|”字符)。 这称为模板过滤器,它是一种过滤变量值的方法。 在这种情况下,日期过滤器以给定格式(在 PHP 的日期函数中找到)格式化 Python 日期时间对象。

您可以根据需要将任意数量的过滤器链接在一起。 您可以编写 自定义模板过滤器 。 您可以编写 自定义模板标签 ,它会在幕后运行自定义 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>

简单地说,它定义了站点的外观(带有站点的徽标),并为子模板提供了要填充的“漏洞”。 这使得站点重新设计就像更改单个文件(基本模板)一样简单。

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

请注意,如果您更喜欢其他系统,则不必使用 Django 的模板系统。 虽然 Django 的模板系统与 Django 的模型层集成得特别好,但没有什么会强迫您使用它。 就此而言,您也不必使用 Django 的数据库 API。 您可以使用另一个数据库抽象层,您可以读取 XML 文件,您可以从磁盘读取文件,或者任何您想要的。 Django 的每一部分——模型、视图、模板——都与下一个分离。


这仅是基本入门知识

这只是对 Django 功能的快速概览。 一些更有用的功能:

  • 与 memcached 或其他后端集成的 缓存框架
  • 一个 联合框架 ,它使创建 RSS 和 Atom 提要就像编写一个小的 Python 类一样简单。
  • 更有吸引力的自动生成的管理功能——这个概述几乎没有触及表面。

接下来的明显步骤是下载Django,阅读教程并加入社区。 谢谢你的关注!