Django概览

因为Django是在快节奏的新闻编辑室环境中开发的,所以它的设计目的是让常见的Web开发任务变得又快又容易。以下是如何用Django编写数据库驱动的Web应用程序的非正式概述。

本文档的目标是为您提供足够的技术细节,以了解Django是如何工作的,但这并不是一个教程或参考资料——但我们两者都有!当你准备好开始一个项目时,你可以 start with the tutorialdive right into more detailed documentation .

设计你的模型

虽然您可以在没有数据库的情况下使用django,但它附带了 object-relational mapper 在其中,用Python代码描述数据库布局。

这个 data-model syntax 提供了许多表示模型的丰富方法——到目前为止,它已经解决了多年来的数据库模式问题。下面是一个简单的例子:

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 makemigrations
$ python manage.py migrate
...\> py manage.py makemigrations
...\> py manage.py migrate

这个 makemigrations 命令查看所有可用的模型,并为不存在的表创建迁移。 migrate 运行迁移并在数据库中创建表,还可以选择提供 much richer schema control .

享受免费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可以自动创建一个专业的,生产就绪的 administrative interface --允许经过身份验证的用户添加、更改和删除对象的网站。所需的唯一步骤是在管理站点中注册模型:

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应用程序的一个典型工作流程是创建模型,让管理站点尽快启动和运行,这样您的员工(或客户)就可以开始填充数据了。然后,开发向公众展示数据的方式。

设计您的URL

一个干净、优雅的URL方案是高质量Web应用程序的重要细节。Django鼓励漂亮的URL设计,并且不会在URL中放任何东西,比如 .php.asp

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

这是一个URLCONF可能看起来像 Reporter/Article 上面的例子:

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, 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的 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样式的“pipe”(字符“”)。这被称为模板过滤器,它是一种过滤变量值的方法。在这种情况下,日期过滤器以给定的格式(在PHP的日期函数中找到)格式化python datetime对象。

你可以根据自己的喜好将过滤器串在一起。你可以写 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>

简单地说,它定义了站点的外观(使用站点的徽标),并为子模板提供了填充的“洞”。这意味着站点的重新设计可以通过更改一个文件来完成——基本模板。

它还允许您使用不同的基本模板创建站点的多个版本,同时重用子模板。Django的创建者已经使用这种技术,通过创建一个新的基本模板来创建截然不同的移动版本的站点。

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

这只是表面

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

  • A caching framework 与memcached或其他后端集成的。

  • A syndication framework 它允许您通过编写一个小的Python类来创建RSS和Atom提要。

  • 更具吸引力的自动生成的管理功能——这一概述几乎没有触及表面。

接下来的步骤是 download Django ,读 the tutorial 并加入 the community . 感谢您的关注!