Django introduction

 

在第一篇Django文章中,我们回答"什么是Django?"这个问题. 并概述此Web框架的特殊之处. 我们将概述主要功能,包括一些高级功能,在本模块中我们将没有时间进行详细介绍. 我们还将向您展示Django应用程序的一些主要构建块(尽管目前您还没有一个可以对其进行测试的开发环境).

Prerequisites: 基本的计算机知识. 对服务器端网站编程的一般了解,尤其是网站客户端与服务器交互的机制 .
Objective: 要熟悉Django是什么,它提供了什么功能以及Django应用程序的主要构造块.

What is Django?

Django是高级Python Web框架,可快速开发安全且可维护的网站. Django由经验丰富的开发人员构建,可以解决大部分Web开发的麻烦,因此您可以专注于编写应用程序而无需重新发明轮子. 它是免费和开源的,拥有一个活跃的活跃社区,出色的文档以及许多免费和付费支持的选项.

Django可帮助您编写以下软件:

Complete
Django遵循"包括电池"的理念,几乎为开发人员提供了"开箱即用"的所有功能. 因为您需要的一切都是一个"产品"的一部分,所以它们可以无缝地协同工作,遵循一致的设计原则,并具有广泛而最新的文档 .
Versatile
Django可以(过去已经)用于构建几乎任何类型的网站-从内容管理系统和Wiki,到社交网络和新闻网站. 它可以与任何客户端框架一起使用,并且可以以几乎任何格式(包括HTML,RSS feed,JSON,XML等)交付内容. 您当前正在阅读的网站是使用Django构建的!

在内部,尽管它提供了您可能想要的几乎所有功能的选择(例如,几个流行的数据库,模板引擎等),但是如果需要,它也可以扩展为使用其他组件.
Secure
Django通过提供一个旨在"做正确的事"以自动保护网站的框架,帮助开发人员避免许多常见的安全错误. 例如,Django提供了一种安全的方法来管理用户帐户和密码,避免了常见的错误,例如将会话信息放在易受攻击的cookie中(而不是cookie仅包含密钥,而实际数据存储在数据库中)或直接存储密码.而不是密码哈希.

密码哈希是通过密码哈希函数发送密码而创建的定长值. Django可以通过使用哈希函数运行输入的密码并将输出与存储的哈希值进行比较,从而检查输入的密码是否正确. 但是,由于该函数的"单向"性质,即使存储的哈希值受到损害,攻击者也很难找出原始密码.

Django默认情况下启用针对许多漏洞的保护,包括SQL注入,跨站点脚本编写,跨站点请求伪造和点击劫持(有关此类攻击的更多详细信息,请参阅网站安全 ).
Scalable
Django使用基于组件的"无共享 "架构(架构的每个部分彼此独立,因此可以在需要时进行替换或更改). 不同部分之间有清晰的分隔,这意味着它可以通过在任何级别添加硬件来扩展流量,以增加流量:缓存服务器,数据库服务器或应用程序服务器. 一些最繁忙的网站已成功扩展Django以满足他们的需求(例如Instagram和Disqus,仅举两个例子).
Maintainable
Django代码是使用鼓励创建可维护和可重用代码的设计原则和模式编写的. 特别是,它利用了"不要自己重复"(DRY)原理,因此没有不必要的重复,从而减少了代码量. Django还促进将相关功能分组到可重用的"应用程序"中,并在较低级别将相关代码分组到模块中(沿模型视图控制器(MVC)模式行).
Portable
Django用Python编写,可在许多平台上运行. 这意味着您不受任何特定服务器平台的束缚,可以在多种Linux,Windows和Mac OS X上运行您的应用程序.此外,许多Web托管提供商都很好地支持Django,这些提供商通常提供特定的基础架构和托管Django网站的文档.

Where did it come from?

Django最初是由一个网络团队在2003年至2005年之间开发的,该团队负责创建和维护报纸网站. 在创建了多个站点之后,团队开始考虑并重用许多通用代码和设计模式. 该通用代码演变为通用的Web开发框架,并于2005年7月作为" Django"项目开源.

从2008年9月的第一个里程碑版本(1.0)到最近发布的版本2.0(2017),Django一直在不断发展和完善. 每个版本都添加了新功能和错误修复,从对新型数据库,模板引擎和缓存的支持到添加"通用"视图功能和类(减少了开发人员必须编写的代码量).一些编程任务).

注意 :查阅Django网站上的发行说明 ,以了解最新版本中发生了哪些变化,以及使Django更好的工作量.

Django现在是一个蓬勃发展的协作式开源项目,拥有成千上万的用户和贡献者. 尽管Django仍然具有反映其起源的某些功能,但Django已经发展成为一个能够开发任何类型网站的通用框架.

服务器端框架的流行程度没有任何现成的,确切的度量标准(尽管像Hot Frameworks这样的网站尝试使用计数GitHub项目数和每个平台的StackOverflow问题之类的机制来评估流行度). 一个更好的问题是Django是否"足够流行"以避免流行平台的问题. 它会继续发展吗? 如果需要可以得到帮助吗? 如果您学习Django,是否有机会获得有酬工作?

根据使用Django的高知名度网站的数量,向代码库做出贡献的人数以及提供免费和付费支持的人数,那么Django是一个受欢迎的框架!

使用Django的知名网站包括:Disqus,Instagram,Knight Foundation,MacArthur Foundation,Mozilla,国家地理杂志,Open Knowledge Foundation,Pinterest和Open Stack(来源: Django主页 ).

Is Django opinionated?

Web框架通常称自己为"有意见的"或"无意见的".

有观点的框架是那些对处理任何特定任务的"正确方法"有看法的框架. 他们通常支持在特定领域中的快速发展(解决特定类型的问题),因为正确的做法通常都被很好地理解和有据可查. 但是,他们在解决其主要领域之外的问题时可能不太灵活,并且倾向于为他们可以使用的组件和方法提供较少的选择.

相比之下,未提出意见的框架对将组件粘合在一起以实现目标的最佳方法甚至应该使用什么组件的限制都少得多. 它们使开发人员可以更轻松地使用最合适的工具来完成特定任务,尽管这需要您自己找到这些组件.

Django是"有点自以为是"的,因此提供了"两全其美"的方式. 它提供了一组用于处理大多数Web开发任务的组件,以及一种(或两种)首选的使用方式. 但是,Django的分离架构意味着您通常可以从许多不同的选项中进行选择,或者根据需要添加对全新选项的支持.

What does Django code look like?

在传统的数据驱动的网站中,Web应用程序等待来自Web浏览器(或其他客户端)的HTTP请求. 收到请求后,应用程序会根据URL以及POST数据或GET数据中的信息确定所需的内容. 然后,根据需要的内容,它可以从数据库读取或写入信息,或执行满足请求所需的其他任务. 然后,应用程序将响应返回到Web浏览器,通常是通过将检索到的数据插入HTML模板中的占位符来动态创建HTML页面供浏览器显示.

Django web applications typically group the code that handles each of these steps into separate files:

  • URL:虽然可以通过单个函数处理来自每个URL的请求,但是编写单独的视图函数来处理每个资源的维护性更高. URL映射器用于根据请求URL将HTTP请求重定向到适当的视图. URL映射器还可以匹配出现在URL中的字符串或数字的特定模式,并将其作为数据传递给视图函数.
  • 视图:视图是一个请求处理程序函数,它接收HTTP请求并返回HTTP响应. 视图通过模型访问满足请求所需的数据,并将响应的格式委托给模板 .
  • 模型:模型是Python对象,用于定义应用程序数据的结构,并提供管理(添加,修改,删除)和查询数据库中记录的机制.
  • 模板:模板是一个文本文件,用于定义文件(例如HTML页面)的结构或布局,并使用占位符表示实际内容. 视图可以使用HTML模板动态创建HTML页面,并使用来自模型的数据填充它. 模板可用于定义任何类型的文件的结构. 它不必是HTML!

注意 :Django将此组织称为"模型视图模板(MVT)"体系结构. 它与更熟悉的Model View Controller体系结构有很多相似之处.

以下各节将使您大致了解Django应用程序的这些主要部分的样子(一旦设置了开发环境,我们将在本课程的后面部分详细介绍).

Sending the request to the right view (urls.py)

URL映射器通常存储在名为urls.py的文件中. 在下面的示例中,映射器( urlpatterns )定义了路由 (特定的URL 模式)和相应的视图函数之间的映射列表. 如果收到的HTTP请求具有与指定模式匹配的URL,则将调用关联的视图函数并将其传递给请求.

urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/<int:id>/', views.book_detail, name='book_detail'),
    path('catalog/', include('catalog.urls')),
    re_path(r'^([0-9]+)/$', views.best),
]

urlpatterns对象是path()和/或re_path()函数的列表(Python列表使用方括号定义,其中项目用逗号分隔,并且可能带有可选的尾部逗号 .例如: [item1, item2, item3,] ).

这两个方法的第一个参数是要匹配的路由(模式). path()方法使用尖括号定义URL的一部分,这些部分将被捕获并作为命名参数传递给视图函数. re_path()函数使用一种灵活的模式匹配方法,即正则表达式. 我们将在以后的文章中讨论这些!

第二个参数是匹配模式时将调用的另一个函数. views.book_detail表示该函数称为book_detail() ,可以在名为views的模块中找到该函数(即,在名为views.py的文件中)

Handling the request (views.py)

视图是Web应用程序的核心,它从Web客户端接收HTTP请求并返回HTTP响应. 在这两者之间,它们编组了框架的其他资源以访问数据库,渲染模板等.

下面的示例显示了一个最小视图函数index() ,它可以由上一节中的URL映射器调用. 像所有视图函数一样,它接收HttpRequest对象作为参数( request ),并返回HttpResponse对象. 在这种情况下,我们对请求不执行任何操作,并且响应仅返回一个硬编码的字符串. 在后面的部分中,我们将向您显示一个更有趣的请求.

# filename: views.py (Django view functions)

from django.http import HttpResponse

def index(request):
    # Get an HttpRequest - the request parameter
    # perform operations using information from the request.
    # Return HttpResponse
    return HttpResponse('Hello from Django!')

注意 :一些Python:

  • Python模块是函数的"库",存储在单独的文件中,我们可能希望在代码中使用它们. 在这里,我们django.http模块导入HttpResponse对象,以便可以在我们的视图中使用它: from django.http import HttpResponse . 还有其他方法可以从模块中导入部分或全部对象.
  • 如上所述,使用def关键字声明函数,并在函数名称后的方括号中列出命名参数; 整行以冒号结尾. 注意下一行是如何缩进的 . 缩进很重要,因为它指定代码行在该特定块内(强制缩进是Python的一项关键功能,也是Python代码如此易于阅读的原因之一).

视图通常存储在名为views.py的文件中.

Defining data models (models.py)

Django Web应用程序通过称为模型的Python对象管理和查询数据. 模型定义了存储数据的结构,包括字段类型 ,还可能包括它们的最大大小,默认值,选择列表选项,文档的帮助文本,表单的标签文本等.模型的定义独立于基础数据库-您可以从项目设置中选择其中之一. 一旦选择了要使用的数据库,就根本不需要直接与之对话-只需编写模型结构和其他代码,Django便会为您处理与数据库通信的所有繁琐工作.

The code snippet below shows a very simple Django model for a Team object. The Team class is derived from the django class models.Model. It defines the team name and team level as character fields and specifies a maximum number of characters to be stored for each record. The team_level can be one of several values, so we define it as a choice field and provide a mapping between choices to be displayed and data to be stored, along with a default value. 

# filename: models.py

from django.db import models 

class Team(models.Model): 
    team_name = models.CharField(max_length=40) 

    TEAM_LEVELS = (
        ('U09', 'Under 09s'),
        ('U10', 'Under 10s'),
        ('U11', 'Under 11s'),
        ...  #list other team levels
    )
    team_level = models.CharField(max_length=3, choices=TEAM_LEVELS, default='U11')

注意 :一些Python:

  • Python支持"面向对象的编程",这是一种编程风格,其中我们将代码组织到对象中,这些对象包括相关数据和用于对该数据进行操作的函数. 对象还可以从其他对象继承/扩展/派生,从而允许共享相关对象之间的共同行为. 在Python中,我们使用关键字class定义对象的"蓝图". 我们可以基于类中的模型创建对象类型的多个特定实例 .

    例如,这里有一个Team类,它是从Model类派生的. 这意味着它是一个模型,将包含模型的所有方法,但是我们也可以为其提供专门的功能. 在我们的模型中,我们定义数据库存储数据所需的字段,并为其指定特定名称. Django使用这些定义(包括字段名称)来创建基础数据库.

Querying data (views.py)

Django模型提供用于搜索数据库的简单查询API. 这可以使用不同的条件(例如精确,不区分大小写,大于等)一次与多个字段匹配,并且可以支持复杂的语句(例如,您可以对拥有团队的U11团队指定搜索以" Fr"开头或以" al"结尾的名称).

该代码段显示了一个视图函数(资源处理程序),用于显示我们所有的U09团队. 粗线显示了如何使用模型查询API来过滤team_level字段具有确切文本'U09'的所有记录(请注意,该条件如何作为带有字段名和参数的参数传递给filter()函数filter()匹配类型,以双下划线分隔: team_level__exact ).

## filename: views.py

from django.shortcuts import render
from .models import Team 

def index(request):
    list_teams = Team.objects.filter(team_level__exact="U09")
    context = {'youngest_teams': list_teams}
    return render(request, '/best/index.html', context)

此函数使用render()函数创建发送回浏览器的HttpResponse . 此功能是快捷方式 ; 它通过组合指定的HTML模板和一些要插入模板的数据(在名为" context "的变量中提供)来创建HTML文件. 在下一节中,我们将展示如何在模板中插入数据以创建HTML.

Rendering data (HTML templates)

Template systems allow you to specify the structure of an output document, using placeholders for data that will be filled in when a page is generated. Templates are often used to create HTML, but can also create other types of document. Django supports both its native templating system and another popular Python library called Jinja2 out of the box (it can also be made to support other systems if needed). 

该代码段显示了上一节中的render()函数调用的HTML模板的外观. 编写此模板的前提是,该模板在呈现时将可以访问名为youngest_teams的列表变量(包含在上述render()函数内部的context变量中). 在HTML框架内部,我们有一个表达式,该表达式首先检查youngest_teams变量是否存在,然后在for循环中对其进行迭代. 在每次迭代中,模板在<li>元素中显示每个团队的team_name值.

## filename: best/templates/best/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Home page</title>
</head>
<body>
  {% if youngest_teams %}
    <ul>
      {% for team in youngest_teams %}
        <li>{{ team.team_name }}</li>
      {% endfor %}
    </ul>
  {% else %}
    <p>No teams are available.</p>
  {% endif %}
</body>
</html>

What else can you do?

前面的部分显示了几乎将在每个Web应用程序中使用的主要功能:URL映射,视图,模型和模板. Django提供的其他一些功能包括:

  • 表单 :HTML表单用于收集用户数据以在服务器上进行处理. Django简化了表单的创建,验证和处理.
  • 用户身份验证和权限 :Django包括一个健壮的用户身份验证和权限系统,该系统在构建时考虑了安全性.
  • 缓存 :动态创建内容比提供静态内容要占用更多的计算资源(且速度较慢). Django提供了灵活的缓存,因此您可以存储已渲染页面的全部或一部分,以便除非必要,否则不会重新渲染该页面.
  • 管理站点 :使用基本框架创建应用程序时,默认情况下包括Django管理站点. 通过它可以轻松地为站点管理员提供一个管理页面,以创建,编辑和查看站点中的任何数据模型.
  • 数据序列化:Django使序列化和将数据作为XML或JSON变得容易. 当创建一个Web服务(一个纯粹提供数据供其他应用程序或站点使用的网站,而自身不显示任何内容)或创建一个由客户端代码处理所有呈现的网站时,这可能很有用.数据的.

Summary

恭喜,您已经完成Django旅程的第一步! 现在,您应该了解Django的主要优点,一些历史知识以及Django应用的每个主要部分的大致外观. 您还应该了解有关Python编程语言的一些知识,包括列表,函数和类的语法.

您已经在上面看到了一些真实的Django代码,但是与客户端代码不同,您需要设置一个开发环境来运行它. 那是我们的下一步.

In this module