• bianchengDjango(python)


    http://c.biancheng.net/django/

    Django MTV和MVC的区别

    1. MVC设计模式

    我们先对 MVC 设计模式进行介绍,它是 Web 设计模式的经典之作,MTV 模式也是在它的基础上衍生而来。

    MVC 是 Model-View-Controller 的缩写,其中每个单词都有其不同的含义:

    • Modle 代表数据存储层,是对数据表的定义和数据的增删改查;
    • View 代表视图层,是系统前端显示部分,它负责显示什么和如何进行显示;
    • Controller 代表控制层,负责根据从 View 层输入的指令来检索 Model 层的数据,并在该层编写代码产生结果并输出。

    MVC 设计模式的请求与响应过程描述如下:

    • 用户通过浏览器向服务器发起 request 请求,Controller 层接受请求后,同时向 Model 层和 View 发送指令;
    • Mole 层根据指令与数据库交互并选择相应业务数据,然后将数据发送给 Controller 层;
    • View 层接收到 Controller 的指令后,加载用户请求的页面,并将此页面发送给 Controller 层;
    • Controller 层接收到 Model 层和 View 层的数据后,将它们组织成响应格式发送给浏览器,浏览器通过解析后把页面展示出来。


    MVC 的 3 层之间紧密相连,但又相互独立,每一层的修改都不会影响其它层,每一层都提供了各自独立的接口供其它层调用,MVC 的设计模式降低了代码之间的耦合性(即关联性),增加了模块的可重用性,这就是 MVC 的设计模式。

    2. MTV设计模式

    那么 Django 的 MTV 又是怎么回事呢?下面讲解 Django 的设计模式。

    Django 借鉴了经典的 MVC 模式,它也将交互的过程分为了 3 个层次,也就是 MTV 设计模式;

    • Model:数据存储层,处理所有数据相关的业务,和数据库进行交互,并提供数据的增删改查;
    • Template:模板层(也叫表现层)具体来处理页面的显示;
    • View:业务逻辑层,处理具体的业务逻辑,它的作用是连通Model 层和 Template 。

    我们按照 MVC 的设计模式对 MTV 进行分析,MTV 设计模式中,用 View 层取代了 Controller 层的位置,用 Template 层取代了原来 View 层的位置。

    初次接触 Django 的设计模式的人,可能会对 Template 层产生疑问,其实 Template 英文的含义就是“模板”的意思,你可以简单理解成,它是一个 HTML 页面 ,HTML 页面的渲染在视图层完成。

    同样我们也对 MTV 设计模式的请求与响应过程进行描述:

    • 用户通过浏览器对服务器发起 request 请求,服务器接收请求后,通过 View 的业务逻辑层进行分析,同时向 Model 层和 Template 层发送指令;
    • Mole 层与数据库进行交互,将数据返回给 View 层;
    • Template 层接收到指令后,调用相应的模板,并返回给 View 层;
    • View 层接收到模板与数据后,首先对模板进行渲染(即将相应的数据赋值给模板),然后组织成响应格式返回给浏览器,浏览器进行解析后并最终呈现给用户。


    通过以上两种设计模式的比较, 我们可以得出 MTV 是 MVC 的一种细化,将原来 MVC 中的 V 层拿出来进行分离,视图的显示与如何显示交给 Template 层,而 View 层更专注于实现业务逻辑。其实在 Django 是有 Controller 层的,只不过它由框架本身来实现,所以我们不用关心它。Django 更关注于M、T 和 V。 

     

    4. Django框架的特点

    相对于 Python 的其他 Web 框架,Django 的功能是最完整的,Django 定义了服务发布、路由映射、模板编程、数据处理的一整套功能。这也意味着 Django 模块之间紧密耦合。

    Django 的主要特点如下:
    • 完善的文档:经过 10 余年的发展和完善,Django 官方提供了完善的在线文档,为开发者解决问题提供支持。
    • 集成 ORM 组件:Django 的 Model 层自带数据库 ORM 组件,为操作不同类型的数据库提供了统一的方式。
    • URL 映射技术:Django 使用正则表达式管理URL映射,因此给开发者带来了极高的灵活性。
    • 后台管理系统:开发者只需通过简单的几行配置和代码就可以实现完整的后台数据管理Web控制台。
    • 错误信息提示:在开发调试过程中如果出现运行异常,Django 可以提供非常完整的错误信息帮助开发者定位问题。

    Django ORM模块精讲

    1. 什么是 ORM?

    ORM (Object Realtional Mapping)即对象关系映射,它是一种基于关系型数据库的程序技术。ORM 允许你使用类和对象对数据库进行操作,这大大提高了对数据库的控制,避免了直接使用 SQL 语句对数据库进行操作。这种程序技术的底层主要是通过映射机制实现的,有兴趣的可以自己研究一下!

    Web 开发中对数据库的操作是必不可少的,然而每种数据库的操作方式以及用法不尽相同。由于 Django 中 ORM 的存在,为我们操作不同种类的数据库提供了统一的方法,ORM 适配了多种常用的关系型数据库,例如 PostgreSQL、MySQL、Oracle、Sqlite3 等。

    如图1是 ORM 与数据库的映射关系图。ORM 把类映射成数据库中的表,把类的一个实例对象映射成数据库中的数据行,把类的属性映射成表中的字段,通过对象的操作对应到数据库表的操作,实现了对象到 SQL、SQL 到对象转换过程。

    Django 把表模型定义为 Model,他需要继承自django.db.models中的 Model 类,只要是与数据表相关的操作,都需要继承这个类。同时ORM 对于数据库的的增删改查,也提供了一些简单的 API,例如 F 查询、Q 查询。

    针对数据库中的字段类型,Django ORM 都有对应的 “xxxField” 来表述,见如下表格。

    字段类型表
    字段说明字段属性
    AutoFiled 默然自增主键(Primary_key=Ture),Django 默认建立id字段为主键。  
    CharFiled 字符类型 Max_length=32,字符长度需要明确
    IntgerFiled 整型 int  
    DateFiled 年月日时间类型 auto_now=True,数据被更新就会更新时间 ;auto_now_add=True,数据第一次参数时产生。
    DateTimeFiled 年月日小时分钟秒时间类型 auto_now=True,数据被更新就会更新时间; auto_now_add=True,数据第一次参数时产生。
    DecimalFiled 混合精度的小数类型 max_digits=3,限定数字的最大位数(包含小数位);decimal_places=2,限制小数的最大位数。
    BooleanFiled 布尔字段,对应数据库 tinyint 类型数据长度只有1位。 值为True或False
    TextFiled 用于大文本  

    上表中列举了经常用到的字段类型,后续如果涉及到其它字段类型再进行介绍。

    2. Django中定义数据表

     那么在 Django 中如何使用 ORM 模块来定义一张数据表呢?在定义数据表之前,我们应该首先理解什么是模型类。

    1) 模型类

    其实模型类本质上属于一个 Python 类,只不过在 Django 中称之为做模型类 ,它是由 django.db.models.Model 派生出的子类,在 Django 中模型类是数据交互的接口,一个模型类代表数据库中的一张数据表,模型类中每一个类属性都代表数据表中的一个字段。

    通过上述介绍,我们可以这样理解:Django 中模型类就相当于 ORM 模块。

    2) 定义数据表

    现在有一张用户信息表 UserInfo,它有两个字段 name 和 password,可以定义如下:

    1. from django.db import models
    2. class UserInfo(models.Model):
    3. name = models.CharFiled(max_length=100)
    4. password = models.CharFiled(max_length=100)

    通过以上代码,UserInfo 数据表就已经创建完成,我们对代码进行逐行解析:

    • 第 1 行,使用 from django.db import models 导入 models 模块;
    • 第 2 行,使用 class 关键字对 UserInfo 表进行类定义,并继承了models 模块中的 Model 类;
    • 第3、4 行,数据表中的字段 name 和 password 是 UserInfo 类的属性,name 和 password 字段类型都是 CharFiled,字段长度均是100。

    3. ORM 管理器对象

    那么应该怎样对数据表进行操作呢?我们可以直接使用类名(即数据表名)来插入数据,下面是插入数据的一种方法:

    1. UserInfo.objects.create(name='jay',password='abc123')

    上面代码插入一条名字是“jay”,密码是“abc123”的数据。读到这里,您可能会对“ objects ”产生疑问,所以在此处讲解一个重要的概念:每个继承自 models.Model 的模型类,都会有一个 objects 对象被同时继承下来,这个对象就叫做“管理器对象”,数据库的增删改查可以用 objects 管理器对象来实现。

    利用 ORM 插入数据有两种方式,上面已经介绍了一种,下面介绍第二种方法,也就是创建 UserInfo 的实例对象,然后调用save()方法保存,代码如下:

    1. Obj=UserInfo(name="jay",password="abc123")
    2. Obj.name="john"
    3. Obj.save()

    上述代码中 name 属性值会被赋值为“john”,最后调用 save()方法保存。

    ORM 的增删改查称为 CURD 操作,下面列举几个常用语句: 

    1. UserInfo.objects.all()#查询表中的所有记录
    2. UserInfo.objects.filter(name_contains='j')#查询表中name含有“j”的所有记录,被使用较多
    3. UserInfo.objects.get(name="john")#有且只有一个查询结果,如果超出一个或者没有,则抛出异常
    4. UserInfo.objects.get(name="john").delete()#删除名字为john的记录
    5. UserInfo.objects.get(name="john").update(name='TOM')#更新数据表的name为TOM

    4. ORM优势与不足

    ORM 模块确实有诸多的优势,比如:

    • 使用该模块只需要面向对象编程,不需要面向数据库编写代码,对数据库的操作转换为对类属性和方法的操作,不用我们编写各种数据库的 SQL 语句。
    • 实现数据模型与数据库的解耦,屏蔽了不同数据库操作上的差异化,不在关注不同数据库内部的操作细节,通过简单更改配置就可以实现数据库的更换而无需更改代码。


    与此同时 ORM 也存在一点不足之处:
    相比直接用 SQL 语句操作数据库会有性能损失,因为在映射的过程中 ORM 需要与 SQL 之间进行转换,根据对象的操作转换成 SQL 语句,根据查询结果转换成对象,所以在映射的过程存在性能损失。

    但是 ORM 的不足带来的这点性能损失是微不足道的,ORM 的优势还是非常突出的。因为这种对象模型和关系型数据库之间的转换方式,给开发者带来了极大的便捷,所以其它语言开发的框架,对 ORM 也有很多应用,比如 Hibernate、IBATIS、EclipseLink 等。

    1. Django的auth模块

    Django 作为功能完善的 Web 框架充分考虑到这一点,它提供的 auth 模块能够快速的实现用户模块的基本功能。

    新建项目后,Django 就把 auth 模块的所有功能提供给了开发者使用,开发者可以调用相应的接口,实现不同的功能需求。auth 模块定义了一张名叫 auth_user 的数据表,该表是 auth 模块的内建用户表,开发者调用 auth 模块的相应接口生成此表,auth_user 表的字段以及字段类型,如下所示。

    +--------------+--------------+------+-----+---------+----------------+
    | Field        | Type         | Null | Key | Default | Extra          |
    +--------------+--------------+------+-----+---------+----------------+
    | id           | int(11)      | NO   | PRI | NULL    | auto_increment |
    | password     | varchar(128) | NO   |     | NULL    |                |
    | last_login   | datetime(6)  | YES  |     | NULL    |                |
    | is_superuser | tinyint(1)   | NO   |     | NULL    |                |
    | username     | varchar(150) | NO   | UNI | NULL    |                |
    | first_name   | varchar(30)  | NO   |     | NULL    |                |
    | last_name    | varchar(150) | NO   |     | NULL    |                |
    | email        | varchar(254) | NO   |     | NULL    |                |
    | is_staff     | tinyint(1)   | NO   |     | NULL    |                |
    | is_active    | tinyint(1)   | NO   |     | NULL    |                |
    | date_joined  | datetime(6)  | NO   |     | NULL    |                |
    +--------------+--------------+------+-----+---------+----------------+
    11 rows in set (0.02 sec)#auth_user表
    

    现在新建一张 auth_user 用户表,并为此表添加一个新用户 user。首先用如下方式引入 auth模块的 User 方法:

    from django.contrib.auth.models import User

    然后通过下面方法创建新用户 user ,如下所示:

    1. user=User.objects.create_user(username='c语言中文网',password='123456',email='664104694@qq.com')
    2. save()#调用该方法保存数据

    同时也可以使用如下方法修改密码:

    1. user.set_password(password='12345abc')#会对原密码进行修改

    根据具体的业务需求,还可以对表的字段进行增加、删除、更改。

    当涉及到用户概念的时候也会产生用户权限问题,比如,如何划分普通用户和超级管理员用户?针对权限问题,Django 也提供了解决问题的方案,auth 模块提供了标准的权限管理系统,它配合 Admin 后台可以快速建立网站管理系统。

    auth 模块提供了认证用户功能,可以用下面方式引入后使用:

    from django.contrib.auth import authenticate

    然后使用关键字传参的方法来传递用户凭证,从而达到用户认证的目的:

    1. user = authenticate(username='c语言中文网',password='12345abc')

    2. auth应用模块的其他作用

    auth 模块还实现一些其它的功能,比如:

    • 用户的登录(login)、退出(logout)功能,封装在 django.contrib.auth 里;
    • 用户权限系统封装在 django.contrib.auth.models.Permission 中 ,可以对用户的权限进行增加、修改、删除;
    • 用户组可以通过 from django.contrib.auth.models.Group 导入后来创建组或者删除组。


    列举一些简单应用方法:

    1. user.user_permission.add(permission)#给某个用户权限的添加权限
    2. group = Group.objects.create(name=group_name)#添加新的用户组
    3. group.save() #保存新建好的用户组
    4. group.delete()#删除用户组

    3. auth模块总结

    auth 模块提供的主要功能总结如下:

    • 实现并维护了用户与用户组的增加、删除、更改功能;
    • 实现了用户权限与用户组权限的增加、删除、更改;
    • 实现了可以自定义用户权限与用户组权限功能。

    除了以上功能外,Django auth 模块还提供了权限验证等功能以及一些常用的方法。

    auth 模块帮助开发人员提高了工作效率,因为每个 Web 站点的权限管理模块或者用户管理模块基本都是相同的逻辑,Django 的 auth 模块使开发者们不必在为一些重复性的逻辑进行构建。在实际开发工作中,用户模块与权限管理模块需要与实际相结合,开发者可以根据业务需求自定义或者重写相应方法,以达到和实际业务相契合的目的。

    1. 后台管理系统的重要性

    我们先考虑一下,Django 为什么要引入后台管理系统呢?

    我们知道,Web 站点上某些内容的改动是后台管理员来完成的,如果管理员直接用 Shell 或者 SQL 语句来修改,不仅麻烦,而且容易操作失误,从而导致数据不一致的结果。假如是一个不懂编程的人呢?应该怎么去操作呢?上述问题,说明了构建一个后台管理系统的重要性,通过后台管理系统为管理员提供一种便捷有效的操作方式。

    后台管理系统主要是对数据表的存储做专门的管理,例如针对微博或者论坛类的站点,管理员需要删除不合规的文章,或者公司内部需要发布新的话题等,这些都是通过数据表的管理实现的。单一功能的后台系统比较容易构建,但是如果功能增多情况下,就需要对多个数据表做管理,这就增加了开发人员的重复性工作。Django 提供的后台管理系统很好的解决了这个问题,以下是后台管理系统主要功能的介绍。

    如图1所示,是后台管理系统的登陆界面,通过超级管理员账户进行登录。


    图1:Admin后台登陆界面
     
    登录后,如图2所示,是 Django Admin 提供的的站点管理功能。


    图2:Admin后台登录后界面

    2. 了解Django后台管理功能

    我们用下面命令来创建超级用户:
    python manage.py createsuperuser
    通过此命令来设置用户名、密码和邮箱。后续章节,还会用到 Admin 后台管理系统,有对此命令的说明。

    Admin 后台管理系统的功能是非常强大的。在以 Django 做为开发框架的小型软件公司,开发人员配置以及时间有限,无法短期内开发一套新的后台管理系统,在这种情况下,一般采用对 Admin 后台管理系统源码稍加改动的方法,把改动后的 Admin 系统作为软件的后台管理系统。

    Admin 后台管理系统提供了用户类别、用户权限以及用户组权限的划分功能,如图3所示,Active (有效)、Staff status(人员状态)、Superuser status(超级用户状态)是用户的三种类别。
    如图4所示,Django 后台管理系统提供了用户权限划分功能。
    当然也提供了用户组权限的分配功能,图5、6所示,分别是添加组和分配组权限。

     

     

     

     
    Django 原生的 Admin 管理界面,虽然没有做太多的修饰,但是开发者可以利用 Model Admin 实现个性化定制,比如字段值的过滤功能、表字段展示的排序、搜索功能等。上面展示的是中文的后台管理界面,原生的 Django 后台管理系统是英文的。所以需要简单设置才可以实现中文模式。

    Django 已经非常的成熟,一些软件社区和第三方平台给 Django 做了很多有用的插件,这使得后台管理界面更加美化,比如 django-admian-bootstrap 等。

    Django视图函数

    1. 第一个视图函数

    在 Django 中,视图函数是一个 Python 函数或者类,开发者主要通过编写视图函数来实现业务逻辑。视图函数首先接受来自浏览器或者客户端的请求,并最终返回响应,视图函数返回的响应可以是 HTML 文件,也可以是 HTTP 协议中的 303 重定向。接下来编写一个简单的视图函数:

    1. from django.http import HttpResponse
    2. def Hello_my_django(request):
    3. return HttpResponse('<html><body>Hello my Django</body></html>')

    下面针对以上 3 行代码做解析:

    1)HttpResponse视图响应类型

    从 django.http 模块中导入 HttpResponse,从它简单的名字我们可以得知,它是一种视图的响应类型。

    2)视图函数参数request

    我们定义了一个名为“Hello_my_django”的函数,Django 规定了,视图函数至少有一个参数,第一个参数必须是 request,request 是 HttpRequest 请求类型的对象,它携带了浏览器的请求信息,所以视图函数的第一个参数必须为 request。

    3)return视图响应

    视图函数要返回响应内容,这里的响应内容是我们用 HTML 标签编写的,把它作为 HttpResponse 的对象返回给浏览器。

    2. 视图函数执行过程

    上面视图函数的代码虽然区区几行,但是已经充分体现了视图层的实现过程。 Django 收到请求以后,首先创建一个带有请求信息的 HttpRequset 对象,将 HttpRequest 的对象 request 作为第一个参数传递给视图函数,视图接收参数后继续向下执行,然后选择加载对应的视图,最后返回 HttpResponse 对象给浏览器。

    通过本节的介绍,我们应该理解 View 视图函数的作用,以及视图函数的定义过程。

    Django模板系统

    本节我们继续使用《Django视图函数》一节中的“Hello_my_django”函数来完成相关知识的讲解。

    1. from django.http import HttpResponse
    2. def Hello_my_django(request):
    3. return HttpResponse('<html><body>Hello my Django</body></html>')

    1. Django的模板系统

    虽然上面的函数也能够顺利完成响应任务,但是我们可以看出这个视图函数的 HTML 代码写在了 Python 定义的函数中。我们先思考一下,如果用以上方法来定义视图函数的话,它是否具有可行性呢?

    有以下两点值得我们思考:

    • 我们知道前端页面需要经常改动。比如,某个电商网站到了双十一搞活动的时候,需要对前端页面做大量的修改,如果将页面放到视图函数中,那么当对前端页面修改的时候,也会使得视图函数发生变化。
    • 从 MTV 设计模式的角度出发,视图层是实现业务逻辑的,在视图层编写代码和编写 HTML 页面是两项可以相互独立的工作,就像公司有开发小组和 UI 小组,它们分别负责不同类型的工作,所以我们为什么不考虑把它们分开呢?如果放到一起,就会增加视图层的复杂度,给程序员维护代码带来困难!


    那么 Django 是如何实现视图函数与 HTML 代码解耦的呢?这就引出我们本节要讲解的知识——模板系统。

    2. 模板系统的应用

    在 Django 中我们把“模板”称之为 Template,它的存在使得 HTML 和 View 视图层实现了解耦。 在《Django MTV和MVC的区别》一文中也提到过 Template,它是设计模式中的 T 层,那么它在 Djang 中又是如何应用的呢?

    其实 T 层应用是这样实现,当创建好一个 Django 项目后,我们在项目的同级目录下创建一个名为 templates 文件夹,对它进行简单的配置后,这个文件夹将被 Django 自动识别。我们可以简单的理解为:文件夹就好比我们所说的 T 层,然而其复杂的实现过程由 Django 框架本身来实现的,所以我们无需关心内部细节。

    下面我们对 Hello_my_django 函数进行一下改造,在 templates 文件中新建一个 HTML 文件,并且将此文件命名为 hello.html,然后在此文件中书写我们的 HTML 代码,如下所示:

    写HTM代码:

    1. <html><body>{{vaule}}</body></html>

    写视图函数:

    1. from django.shortcuts import render
    2. def hello_my_django(request):
    3. return render(request,"hello.html",{"vaule":"hello my Django"})

    看完上述代码,你可会有些不理解,这属于正常现象,因为我们还有许多的知识未涉及到,继续看我们教程,你会很快理解它。对于上述代码,我们先通俗易懂的讲解一下。

    1) 模板传参

    hello.html 文件中的 {{vaule}} 是一个模板的变量,视图函数必须把数据形成字典的形式才可以传递给模板,这就是“模板传参”。

    2) render方法

    render 是 View 层加载模板的一种方式,它封装在 django.shortcuts 模块中,render 方法使用起来非常方便,它首先加载模板,然后将加载完成的模板响应给浏览器。

    URL是什么

    1. 为什么了解URL

    URL 即统一资源定位符,它是用来表示互联网上的某个资源地址,互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。URL 最初是由蒂姆·伯纳斯·李发明的,并使用它作为万维网的地址,现在它已经被万维网联盟编制为互联网标准 RFC1738。

    学习本节知识为下一节的内容打下铺垫,在 Django 中就是通过 URL 配置来实现页面访问的。无论用什么 URL 地址访问 Web 站点资源,都需要开发者对 URL 地址进行设计,所以学习本节知识是必需的!

    2. URL语法格式详解

    URL 的语法格式为:

    protocol://hostname[:port]/path[?query][#fragment]

    请看下面的例子:

    https://www.baidu.com/movie/movieshow?id=234&number=1314#name

    我们对上述语法格式做简单说明:

    1) protocol(协议)

    protocol 是指网络传输协议,以下是经常用到的几个协议:

    • http,通过 HTTP 协议访问该资源,格式 http://;
    • https,通过安全的 HTTPS 协议访问该资源, 格式 https://;
    • file,资源是本地计算机上的文件,格式 file:///;
    • ftp,通过 FTP访问资源,格式 FTP://。

    2) hostname(主机名)

    是指存放资源的服务器的域名、主机名或 IP 地址。有时,在主机名前也可以包含连接到服务器所需的用户名和密码(格式:username:password@hostname)。

    3) port(端口号)

    port 是一个可选的整数,它的取值范围 是 0-65535。如果 port 被省略时就使用默认端口,各种传输协议都有默认的端口号,如 http 的默认端口为 80,https 的端口是 443。

    4) path(路由地址)

    由零个或多个/符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。路由地址决定了服务端如何处理这个请求。

    5) query (查询)

    ?开始到#为止,它们之间的部分就是参数,又称搜索部分或者查询字符串。这个部分允许有多个参数,参数与参数之间用&作为分隔符。本例的参数部分为id=234&number=1314

    6) fragment(信息片断)

    它用于指定网络资源中的片断,例如一个网页中有多个名词解释,那么可使用 fragment 直接对它们定位。例子中的信息片段是#后的 name。#代表网页中的一个位置而 name 就是这个位置的标志符号,当浏览器读取到上述 URL 后,浏览器将直接展示该位置。

    Django路由系统精讲

    1. Django 路由系统应用

    一个用户向 Web 站点发送请求,是通过 URL 实现的,当 Web 服务器端接收到用户请求后,它又是怎么处理的呢?通过 MTV 的设计模式,我们可以得知,首先用户请求会到达相应的视图函数,那么视图函数又是怎样找到相应的访问资源的呢,在这里就用到了“路由系统”。

    Django 中利用 ROOT_URLCONF 构建了 URL 与视图函数的映射关系。在 django.conf.urls 中封装了路由模块,新建的 Django 项目中提供了 urls.py(创建项目后自动生成的配置文件) 路由配置文件,urls.py 文件中定义了一个 urlpatterns 的列表,它是由 url( ) 实例对象组成的列表,Django 中 url 的定义就是在这个列表完成的。

    1. from django.conf.urls import url
    2. urlpatterns=[
    3. url(r '^admin/',admin.site.urls),
    4. ...
    5. ]

    后台 Admin 管理系统的路由就定义在了列表第一个位置,下面我们对路由的语法格进行简单说明:

    1. url(regex,view,name=None)

    上述 url 的参数解析如下:

    • regex,匹配请求路径,用正则表达式表示;
    • view,指定 regex 匹配路径所对应的视图函数的名称;
    • name,是给 url 地址起个别名,在模板反向解析的时候使用,这个知识点后面还有介绍。

    1)配置第一个URL实现页面访问

    在 urls.py 的同级目录下,新建 views.py 文件,把它作为编写视图函数的 View 层,然后在 views.py 中编写如下代码:

    1. from django.http import HttpResponse
    2. def page_view(request):
    3. html='<h1>欢迎来到,C语言中文网,网址是http://c.biancheng.net</h>'
    4. return HttpResponse(html)

    假如现在有一个名叫 “myject”的 Django 项目,首先需要在 urls.py 文件中导入 views.py, 这么做的目的是把 URL 与视图层进行绑定,然后在 urls.py 的 urlpatterns 中编写如下代码:

    1. from django.conf.urls import url
    2. from django.contrib import admin
    3. from myject import views
    4. urlpatterns = [
    5. url(r'admin/', admin.site.urls),
    6. url(r'^page$/',views.page_view),]

    上述代码解析:

    • 代码的前 3 行分别对 URL 模块、admin 模块、以及视图层 views 做了导包操作;
    • 路径地址被定义为 page,也就是在本机浏览器地址栏输入:http://127.0.0.1:8000/page 进行访问,views.page_view将 page/ 路径与对应的视图函数进行了关联。


    那么通过上述的代码就完成了路由的配置。在项目运行后,通过访问对应的地址就可以得到相应的页面了,如下图所示:

    1)正则与正则分组使用

    在 Django 的路由系统中,正则匹配得到了充分的使用,比如要匹配任意 1000个页面,那么正则匹配路由地址可以写为:

    1. url(r'^page(\d+)',views.page_view)

    同时也可以使用正则分组的方式匹配地址:

    r'^(\d+)/(\w{3})/(\d+)' 匹配类似于 http://127.0.0.1:8000/521/Django/1314的地址

    2)正则捕获组使用

    捕获组:

    1. url(r'^person/(?P<name>\w+)/(?P<age>\d{1,2})',views.person_view)

    在视图函数层,用函数关键字传参的方法,将 name 与 age 传递给视图函数。

    1. def person_view(request,name,age):
    2. s = '姓名: ' + name
    3. s += ' 年龄: ' + age
    4. return HttpResponse(s)

    一个分组表示一个参数,多个参数需要使用多个分组,并且使用 / 隔开。

    2. path()与re_path()

    Django 的路由系统使用方法简洁且容易理解,这大大降低了如何配置 URL 的难度。

    在 Django 2.0 版本中推出了新的用法 path() 和 re_path(),进一步提升了 Django 的效率与使用的简洁性。2.0 版本以后虽然推出了新的方法,但是 1.0 版本的 URL 用法仍然可以在 2.0 版本中使用,向前做了兼容。

    Django中间件

    中间件是一个插件系统,嵌入在 Django 的 Request 和 Response 之间执行,可以对输入和输出内容作出修改,它是处理所有请求与响应的通用框架组件。

    1. Django默认自带中间件

    中间件本质上是一个 Python 类,类里定义了一些函数,这些函数在视图函数执行的前后调用,它们被形象的称之为“钩子函数”。Django 不仅向我们提供了丰富的中间件,而且也可以使用 Django 的中间件接口来实现自定义中间件。下面就是创建 Django 项目后,默认生成的中间件,配置在 settings.py 文件中。

    1. MIDDLEWARE = [
    2. 'django.middleware.security.SecurityMiddleware',
    3. 'django.contrib.sessions.middleware.SessionMiddleware',
    4. 'django.middleware.common.CommonMiddleware',
    5. 'django.middleware.csrf.CsrfViewMiddleware',
    6. 'django.contrib.auth.middleware.AuthenticationMiddleware',
    7. 'django.contrib.messages.middleware.MessageMiddleware',
    8. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    9. ]

    1)中间的执行与响应顺序

    项目创建后,所有中间件都是默认激活的状态。当然你可以通过代码注释,将某个中间件关闭,这需要您根据具体的业务需求来操作 。Django 同时规定了中间件的执行顺序与配置关系,按照如上列表,从上至下行依次执行每一个中间件,但是返回响应结果的时候,整好相反,是从下至上。

    如图所示,从浏览器发出一个请求 Request,最后得到一个 HttpResponse 响应 ,这个请求传递与响应返回的过程如下图所示:

    中间件作为一个可插拔的组件对外提供服务,每个中间件都负责完成一些特定的功能。例如,Django 包含一个中间件 “AuthenticationMiddleware”,它的作用是将会话和用户请求进行关联。

    中间件定义的钩子函数,是在视图函数执行的前后调用的,它们的执行过程如下所示:

    1)在调用视图之前

    如图1所示,在请求阶段,Django 按照自定义的顺序自上而下地应用中间件。这个过程执行两个钩子函数 process_request() 和 process_view(),它们都是在视图函数执行前调用的。

    2)在调用视图之后

    如图1所示,在响应阶段,中间件从下往上返回 HttpResponse,这个过程有三个挂钩函数可供选择:

    • process_exception() (只有当视图引发异常时调用);
    • process_template_response() (仅适用于模板响应);
    • process_response()。

    2. 中间件的作用总结

    那我们可以总结一下,中间件是介于 request 与 response 之间的一道处理过程,相对比较轻量级。我们可以通过中间件来修改请求,例如,被传送到视图函数中的 HttpRequest 对象,也可以修改视图函数返回的 HttpResponse 对象。

    对于请求与响应的顺序总结如下:请求发出自上而下,响应返回自下而上。

    django.middleware.clickjacking.XFrameOptionsMiddleware

    我们拿最后一个中间件举例说明,它的 process_request 方法最后一个执行,而它的 process_response 方法却是最先执行。

    Django Cache缓存系统

    1. 缓存技术的作用

    缓存是指保存一些计算开销较大的数据,可以是某个网页,也可以是网页的一部分,或者仅仅只是格式化的数据,合理运用缓存技术可以减少数据库访问次数,不用每次都到数据库中读取数据,从而优化了网页的访问速度。

    缓存系统真正的提高了 Web 站点执行效率,常被用来缓存用户经常访问的页面,比如网站的首页等,用户再次访问的时候直接返回已经缓存的内容,从而减小了 Web 服务器的压力。

    2. Django 缓存系统

    Django 提供了一个健壮的缓存系统,可以保存动态页面,这样就不必每次都把相同的请求进行重复计算。并且 Django 还提供了不同级别的缓存粒度,可以缓存特定视图的输出,或者只缓存某些特定的片段,比如网站自动跳出的咨询栏等,或者也可以缓存整个站点。

    同时 Django 还支持多种缓存类型,可以根据实际情况来选择用哪种类型,例如 Memcached、数据库、文件系统等。

    Memcached 是 Django 支持的最快、最高效的分布式高效缓存系统,它是一种完全基于内存的缓存服务器。它被 Facebook 、维基百科等网站使用,从而减少数据库的访问并显著提高网站的性能。

    使用 Django 框架开发应用程序,最大的优点就是快速高效。经过第一章学习,我们对 Django 框架有了初步的认识,当新建好一个 Django 项目时,Django 就已经设置好了用户系统、后台系统、权限验证,中间件以及缓存系统等功能,这些功能极大方便了 Web 开发者的工作。

    搭建Django开发环境

    搭建开发环境不仅是个繁琐的过程,而且很容易出错,搭建 Django 开发环境主要分为以下 5 个步骤,我们将依次展开介绍: 

    • 安装 Python 解释器
    • 安装 MySQL 数据库
    • 安装 Python 包管理器 pip
    • 安装 Pycharm IDE
    • 安装 Django

    1. 安装Python解释器

    Django 是一款完全基于 Python 的 Web 开发框架,所以安装 Python 解释器是毋庸置疑的。本教程是以 Django 2.2.10 版本来展开学习的,它支持 Python3.5、3.6 以及 3.7,如果你使用的是 Linux 或 Mac 操作系统,你的电脑中已经安装了 Python。因为这两种操作系统的部分功能是使用 Python 语言实现的,所以在它们出厂的时候就对 Python 进行内置安装,可以使用如下命令检查 Python 版本:

    C:\Users\Administrator>python --version
    Python 3.7.4

    Python 版本的选择只要符合 Django 的要求即可,Python 的安装在这里就不加赘述了,可以参见本网站《Python编程环境搭建》,它提供了 Linux、MacOS、Windows 三个平台安装 Python 的方式!

    2. 安装MySQL数据库

    为了达到数据存储的目的,我们需要对数据库进行安装,Django 对关系型数据库有非常好的支持,虽然它自带一个轻量级的 SQLite 数据库,但为了切合 Django 的实际应用场景,我们选择 MySQL 这样的企业级应用数据库。MySQL 安装可以参见本网站《MySQL安装教程,包含所有平台(图解)》,根据自己电脑的操作系统类型选择相应的安装方式。笔者建议安装 MySQL5.5 或以上版本,本教程以 Mysql5.7 与 Django 配合使用。

    如果想通过 Windows CMD 界面操作 MySQL 数据库,那么需要以管理员身份运行 CMD 命令提示符,如图所示:3. 安装Python包管理器

    世界各地开发者基于 Python 编写的各种软件也是以一种标准的包形式进行分享的,称为“第三方包”。官方专门建立了“Python 包索引”(即 PyPI: https://pypi.python.org/) 用来统一发布第三方包,相当于是 Python 软件的免费应用市场。Python 标准库和“第三方包”共同组成了 Python 开源软件市场。Python 之所以强大,不仅是因为它支持 Web 开发,而且支持当下比较热门的数据分析以及人工智能这些前沿技术,这些技术的实现也得益于 Python 的“第三方包”。 

    就像手机上的软件应用市场一样,帮我们管理着种类繁多的软件。Python 同样也需要一个工具去下载维护这些“第三方包”,这就用到了 pip 包管理器,它是一种自动安装、升级、配置和删除包的软件,无需自己动手下载、安装和维护软件,除此之外包管理器还帮助我们解决以下几个问题:

    • 包对环境的的依赖问题;
    • 包之间存在冲突的问题;
    • 包的系统路径指定和维护问题。

    这些繁琐的工作都交给 pip 包管理器去处理。

    Python3.4 及以上本版本,均对 pip 做了内置安装,所以在安装 Python 时直接安装 3.7 版本即可,省去不必要的麻烦。可以使用如下命令将 pip 升级至最新版:

    python -m pip install -U pip

    pip 最常用的命令有以下几个:

    • 查看版本:pip --version
    • 安装:pip install 包名
    • 升级:pip install -U 包名
    • 卸载:pip uninstall 包名
    • 列出已经安装的包:pip list

    提示:在这里简单介绍一下 pip3,如果你的系统安装了 Python 2.7 和 Python 3.x 两个版本的时候,那么 pip 对应的是 Python 2.7,pip3 对应的是 Python 3.x。

    4. 安装 Pycharm IDE

    PyCharm 是一种 Python IDE,它是一个可跨平台的开发工具,被认为是最好用的 Python IDE 之一,它带有一整套在使用 Python 语言开发时提高效率的工具,比如调试、语法高亮、Project 管理、代码跳转、智能提示、自动完成等。此外,该 IDE 对 Django 框架下的专业 Web 开发提供了良好的支持。Pycharm 安装可以参见本网站《PyCharm下载和安装教程(包含配置Python解释器)》。

    Django创建第一个项目

    1. 第一个项目BookStore

    1) BookStore项目创建

    我们创建一个名为 Book 的文件夹,用它来承载 BookStore 项目。在 CMD 命令行使用cd命令进入新建的 Book 文件夹,然后使用如下命令创建 BookStore 项目:

    django-admin startproject BookStore

    startproject 是 django-admin 的子命令,它是专门用来创建 Django 项目的。

    我们可以通过tree命令来查看 Book 文件夹的目录树结构,下面是命令执行的过程:

    C:\Users\Administrator>cd Desktop\Book
    C:\Users\Administrator\Desktop\Book>django-admin startproject BookStore
    C:\Users\Administrator\Desktop\Book>cd ..
    C:\Users\Administrator\Desktop>tree /f Book
    C:\USERS\ADMINISTRATOR\DESKTOP\BOOK
    └─BookStore
        ├─manage.py
        │
        └─BookStore
              ├─settings.py
              ├─urls.py
              ├─wsgi.py
              ├─__init__.py


    tree 命令让我们清晰地认识了 Django 项目的目录结构。我们发现在 Book 文件夹下存在一个名为 BooKStore 的子目录,这个子目录就是我们使用命令创建的项目,而在该目录下仍然存在一个同名的 BookStore 的二级子目录和一个 manage.py 文件,如图 1 所示:

    BookStore 二级子目录专门用来承载 Django 项目的配置文件,如图 2 所示:

    2. Django项目配置文件

    二级子目录 BookStore 下的文件称为 Django 项目的配置文件, 它们在创建项目的时候自动生成。下面我们对上述涉及到的文件进行详细的说明:

    1) manage.py文件

    一级子目录中的 manage.py 文件是管理 Django 项目的重要命令行工具,它主要用于启动项目、创建应用和完成数据库的迁移等。

    2) __init__.py文件

    二级子目录中的 __init__.py 文件用于标识当前所在的目录是一个 Python 包,如果在此文件中,通过 import 导入其他方法或者包会被 Django 自动识别。

    3) settings.py文件

    settings.py 文件是 Django 项目的重要配置文件。项目启动时,settings.py 配置文件会被自动调用,而它定义的一些全局为 Django 运行提供参数,在此配置文件中也可以自定义一些变量,用于全局作用域的数据传递。

    4) urls.py文件

    url.py 文件用于记录 Django 项目的 URL 映射关系,它属于项目的基础路由配置文件,路由系统就是在这个文件中完成相应配置的,项目中的动态路径必须先经过该文件匹配,才能实现 Web 站点上资源的访问功能。

    5) wsgi.py文件

    wsgi.py 是 WSGI(Web Server Gateway Interface)服务器程序的入口文件,主要用于启动应用程序。它遵守 WSGI 协议并负责网络通讯部分的实现,只有在项目部署的时候才会用到它。

    如何启动Django项目详解

    1. 启动项目并实现访问

    在 CMD 命令行工具中,执行cd命令进入 Book/BookStore 目录下,通过《Django创建第一个项目》一节,我们知道在 BookStore 子目录下有一个 manage.py 文件,而这个文件的主要作用之一就是用来启动项目的,所以必须和 manage.py 文件处于同一个路径下才可以执行启动命令,启动项目的命令如下所示:

    cd /Users/hanwenda/pythonProject/Book/BookStore
    python3 manage.py runserver
    http://127.0.0.1:8000
    1) 启动项目命令介绍
    我们使用如下命名启动了项目:
    python manage.py runserver
    Django 的默认启动端口是 8000,当然也可以选定其他端口来启用。比如,你想在你的计算机上启动多个 Django 项目,那么就需要多个端口启动不同的项目,否则就会出现端口重用的问题,那么如何通过指定端口号启动项目呢?我们可以使用如下命令格式:
    python3 manage.py runserver 6000
    manage.py help

    settings.py配置文件详解

    1. settings.py文件介绍

    下面对 settings.py 配置文件涉及到的知识点进行依次讲解:

    1) BASE_DIR

    它用于绑定当前项目 BookStore 所在的绝对路径,项目中的所有的文件都需要依赖此路径,绑定路径的方法如下:

    1. BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    __file__是 Python 的语法,显示当前文件的位置,os.path.abspath(__file__) 方法返回当前文件的绝对路径。

    2) SECRET_KEY

    这个变量的本质是一个加密的盐,它一般配合加密算法 Hash、MD5 一起使用。例如用户密码的加密或者建立会话时用到的 sessionid 都需要用到 SECRET_KEY 。在实际的开发工作中,一般将它保存在系统的环境变量中以确保加密盐的安全。

    3) DEBUG

    用于配置 Django 项目的启用模式,有两种取值方式:

    • DEBUG = True用于在开发环境中使用,属于调试模式,在项目的运行过程中会暴露一些错误信息以方便调试。
    • DEBUG = False用于线上环境,表示不启用调试模式。

    4) ALLOWED_HOSTS

    用于配置能够访问当前站点的域名(IP地址),当 DEBUG = False 时,必须填写,有以下三种使用方法:

    • [],空列表,表示只有1217.0.0.1,localhost能访问本项目;
    • ['*'],表示任何网络地址都能访问到当前项目;
    • ['192.168.1.3', '192.168.3.3'] 表示只有当前两个主机能访问当前项目。

    提示:如果是在局域网,让其它主机也能访问此站点,应使用 ALLOWED_HOSTS=['*'] 的方式。

    5) INSTALLED_APPS

    这个参数是指当前项目中用来安装的应用(APP)的列表,Django 把默认自带的应用放在这个列表里,比如 Admin 后台应用、Auth 用户管理系统等,前面我们也对这两个模块做了相应的介绍,在 Django 中把它们称之为“应用”。

    我们可以根据自己的项目需求对其进行增加或删除,比如公司要单独开发一个后台管理系统,就可以把第一项 admin 注释掉。开发时自己编写的应用都必须在这个变量表中进行注册才能生效。所以这个列表需要经常的改动。

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]

    6) MIDDLEWARE

    它用于注册中间件,我们在《Django中间》中进行了介绍,Django 默认加载了一些中间件。例如,用于处理会话的 SessionMiddleware 等,同样我们可以对这些中间件进行添加或者注释。

    7) ROOT_URLCONF

    1. ROOT_URLCONF = 'BookStore.urls'

    它指定了当前项目的根 URL,是 Django 路由系统的入口。

    8) TEMPLATES

    它用于指定模板的配置信息,列表中每一元素都是一个字典。如下所示是 Django 默认自带模板引擎:

    1. {'BACKEND':'django.template.backends.django.DjangoTemplates'

    9) WSGI_APPLICATION

    1. WSGI_APPLICATION = 'BookStore.wsgi.application'

    项目部署时,Django 的内置服务器将使用的 WSGI 应用程序对象的完整 Python 路径。

    10) DATABASES

    1. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }

    它用于指定数据库配置信息,这里默认配置的是 Django 自带的 sqllite3 数据库。Django 支持多种数据库,在这个字典变量中更改数据库配置。在后续章节我们将对 Mysql 数据库配置进行讲解。

    11) AUTH_PASSWORD_VALIDATORS

    这是一个支持插拔的密码验证器,且可以一次性配置多个,Django 通过这些内置组件来避免用户设置的密码等级不足的问题。

    1. AUTH_PASSWORD_VALIDATORS = [
    2. {
    3. 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    4. },
    5. {
    6. 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    7. },
    8. {
    9. 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    10. },
    11. {
    12. 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    13. },
    14. ]

    12) LANGUAGE_CODE和TIME_ZONE

    分别代表语言配置项和当前服务端时区的配置项,我们常用的配置如下所示:

    • LANGUAGE_CODE 取值是英文:'en-us'或者中文:'zh-Hans';
    • TIME_ZONE 取值是世界时区 'UTC' 或中国时区 'Asia/Shanghai'。

    13)  USE_118N和USE_L10N

    项目开发完成后,可以选择向不同国家的用户提供服务,那么就需要支持国际化和本地化。USE_118N 和 USE_L10N 这两个变量值表示是否需要开启国际化和本地化功能。默认开启的状态。

    提示:USE_I18N = True 与 USE_L10N = True 其的 I18N 指的是国际化英文缩写,L10N 指的是本地化英文缩写。

    14) USE_TZ=True

    它指对时区的处理方式,当设置为 True 的时候,存储到数据库的时间是世界时间  'UTC'。

    15) STATIC_URL= '/static/'

    它指的是静态资源的存放位置,静态资源包括 CSS、JS、Images。比如我们要在项目中添加一些图片,通常这些静态图片被存放在新建的 static 目录下,这样就实现了通过 STATIC_URL= '/static/' 路径对静态资源的访问。

    如何配置settings.py文件

    1) 修改语言与时区配置

    在项目中设置语言、时区是必不可少的,打开 settings.py 文件,在文件的末尾部分找到相应的变量进行配置,如下所示:

    LANGUAGE_CODE='zh-Hans'  #设置为中文模式
    TIME_ZONE='Asia/Shanghai'   #设置为中国时间

    2) 设置时区不敏感

    当 USE_TZ 设置为 False 时,表示对时区不敏感,并且让数据库时间符合本地时区。

    3) 配置项目所需数据库

    在 Django 项目中配置数据库是必不可少的,我们使用 MySQL 作为项目的数据库,下面是 Django 默认配置的 sqlite3 数据库:

    1. DATABASES = {
    2. 'default': {
    3. 'ENGINE': 'django.db.backends.sqlite3',
    4. 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    5. }
    6. }

    在配置 MySQL 数据库之前,先进入 MySQL 命令行界面为项目建库,使用如下命令:

    CREATE DATABASE bookstoredb;

    然后在 settings.py 文件中配置 MySQL 数据库,如下所示:

    1. DATABASES = {
    2. 'default': {
    3. 'ENGINE': 'django.db.backends.mysql',
    4. 'NAME': 'bookstoredb',
    5. 'USER': 'root',
    6. 'PASSWORD': '123456',
    7. 'HOST': '127.0.0.1',
    8. 'PORT': '3306',
    9. }
    10. }

    提示: 配置时需要注意,MySQL 数据库的 USER 和 PASSWORD 请根据自己的设置来配置。不要 Copy 上述代码。

    下面我们对上述 DATABASES 中的字典元素进行介绍:

      • ENGINE:指定使用的数据库引擎,可以通过 Django.db.backends 来查看哪些数据库可以与 Django 配合使用;
      • NAME:指定项目所用的数据库名字;
      • USER:是 MySQL 用户名,是在安装 MySQL 时设定的,或者是为项目单独创建的用一个户;
      • PASSWORD:指的是数据库的密码;
      • HOST:数据库服务器地址,这里是本地环境开发,所以使用本地回送地址 127.0.0.1;
      • PORT:MySQL 数据库的端口号,默认端口是 3306。

    PyMySQL 模块是 Python 的一个第三方模块, Python 3 与 MySQL 数据库的连接就是由它实现的。然后我们进行以下操作:找到 init.py 配置文件,在文件中加上如下代码:

    1. import pymysql
    2. pymysql.install_as_MySQLdb()

    这就表示用 PyMySql 代替 MySQLdb 来实现 Django 与 MySQL 数据库的交互。按照上述的方式配置完成后,再执行迁移命令,就可以顺利完成项目的初始化工作了。

    3. migrate与makemigrations命令详解

    通过图 3 所示,我们能够得出执行完 migrate 命令后,在数据库 bookstoredb 中就生成了 admin、auth、session 等应用所需要的数据表,我们可以进入 MySQL 命令界面,使用如下命令查看创建了哪些表。

    SHOW TABLES;

    输出结果如下所示,这就是在项目数据库中生成的表:

    mysql> show tables;
    +----------------------------+
    | Tables_in_bookstoredb      |
    +----------------------------+
    | auth_group                 |
    | auth_group_permissions     |
    | auth_permission            |
    | auth_user                  |
    | auth_user_groups           |
    | auth_user_user_permissions |
    | django_admin_log           |
    | django_content_type        |
    | django_migrations          |
    | django_session             |
    +----------------------------+
    10 rows in set (0.01 sec)

    这里使用一个命令就完成了数据库的迁移工作,但是有两点问题值得我们思考,migrate 是怎么知道要创建哪些表的,而且如果这些表修改了,它又怎样去维护这些表与数据库中已经迁移的表保持一致呢?下面我们来解答这个疑惑。

    Django 对于数据库的迁移工作通过两个命令来实现,一个就是我们上面介绍的 migrate 命令,另个命令如下所示:

    python manage.py makemigrations

    makemigrations 命令会检测应用目录下是否存在 migrations 目录,如果没有则进行创建。首先,会根据应用的表结构定义生成一个 0001_inital.py 文件,里面定义了数据表的结构。

    1) makegrations生成数据库迁移文件

    当数据表更改后,我们首先执行 makemigrations 命令,然后 Django 会重新生成一个新的数据库迁移文件用来记录表结构之间的差异,命名规则是对上一个迁移文件的序列号加1,如 0002_xxx、0003_xxx。

    2) migrate执行数据库迁移命令

    之后,再次执行 migrate 命令让新的迁移文件生效并同步回数据库,从而完成表结构定义的修改。对于 Django 内置的应用,数据库迁移文件已经生成好了,所以直接使用 migrate 命令即可。

    3) 完成数据库迁移总结

    每一次数据表更改后,都需要执行下面的两个命令,它们的执行顺序如下所示:

    python manage.py makemigrations
    python manag.py migrate


    为了保证已经完成的迁移工作不会重复的执行,Django 会把每一次数据库迁移记录到 django_migrations 表中,每一次执行 migrate 命令前都会比较迁移文件是否已经记录在表中了,只有没出现过的才会执行。若想查看当前项目的第一次 migrate 生成的迁移记录,可以在 MySQL 命令行界面使用如下命令查看 :

    select * from django_migrations;

    Django项目创建第一个应用

    1. 创建应用

    Django 的设计目标是让开发者关注应用的功能逻辑的实现,所以,创建应用的过程是非常简单的,利用 manage.py 提供的 startapp 命令就可以创建一个APP,具体命令如下所示:

    python manage.py startapp index

    startapp 同样也属于 manage.py 的子命令,用来创建 Django 的应用。执行这个命令不会在 CMD 命令行看到任何输出,但是,可以在 manage.py 的同级目录下看到多出了一个 index 目录,我们使用 tree 命令来查看 index 的目录结构如下所示:

    C:\Users\Administrator\Book\BookStore>python manage.py startapp index
    C:\Users\Administrator\Book\BookStore>tree /f index
    C:\USERS\ADMINISTRATOR\BOOK\BOOKSTORE\INDEX
    ├─ admin.py
    ├─ apps.py
    ├─ models.py
    ├─ tests.py
    ├─ views.py
    ├─__init__.py
    │
    └─ migrations
           ├─__init__.py
    
    

    上面就是一个 index 应用的结构组成,我们对这些文件做逐一的解释:

    • admin.py 用于将 Model 定义的数据表注册到管理后台,是 Django Admin 应用的配置文件;
    • apps.py 用于应用程序本身的属性配置文件;
    • models.py 用于定义应用中所需要的数据表;
    • tests.py 文件用于编写当前应用程序的单元测试;
    • views.py 用来定义视图处理函数的文件;
    • 一级目录下的 __init__.py 文件标识 index 应用是一个 Python 包;
    • migrations 目录用于存储数据库迁移时生成的文件,该目录下的 __init__.py 文件标识 migrations 是一个 Python 包。


    这就是 index 应用涉及到的所有文件,当然在实际的开发工作中,该应用目录下的文件也不是一成不变的,开发者根据自己的需要会相应的增加文件或者子目录,比如 urls.py 文件或者存储静态文件的 static 目录等。所以大家千万不要认为 Django 框架自动生成的目录,无需我们做其他操作或者更改,这是使用 Django 的一个误区。

    2. 应用的添加

    应用创建完成后,我们还需要在 settings.py 配置文件中对其进行添加。在《settings.py配置文件详解》一文中我们已经对 INSTALLED_APPS 做了介绍,把我们创建的应用添加到这个列表,如下所示:

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'index',
    ]

    用如上方式添加完成后,就可以让 index 应用的和整个项目融为一体了。

    Django ORM进阶应用

    由于每一个数据表对应一个 Model 定义,每一个 Model 都是一个 Python 类,所以,Model 之间是可以继承的。Django 规定,所有的 Model 都必须继承自:

    django.db.models.Model

    可以直接继承,也可以间接继承。Model 中的所有字段都是 django.db.models.Field的子类,Django 会根据 Field 的类型确定数据库表的字段类型。Django 内置了数十种 Field 字段类型。

    1. ORM定义项目数据表

    下面我们用 ORM 定义 index 应用所需的数据表,首选找到 index 应用下的 models.py 文件,在文件里添加如下代码:

    1. class Book(models.Model): #创建 book 表
    2. title=models.CharField( max_length=30,unique=True, verbose_name='书名')
    3. public=models.CharField(max_length=50,verbose_name='出版社')
    4. price=models.DecimalField(max_digits=7,decimal_places=2,verbose_name='定价')
    5. def default_price(self):
    6. return '¥30'
    7. retail_price=models.DecimalField(max_digits=7,decimal_places=2,verbose_name='零售价',default=default_price)
    8. def __str__(self):
    9. return "title:%s pub:%s price:%s" % (self.title, self.public, self.price)
    10. class Author(models.Model): #创建作者表
    11. name=models.CharField(max_length=30,verbose_name='姓名')
    12. email=models.EmailField(verbose_name='邮箱')
    13. def __str__(self):
    14. return '作者:%s'%(self.name)
    15. class UserInfo(models.Model): #创建用户信息表
    16. username=models.CharField(max_length=24,verbose_name='用户注册')
    17. password =models.CharField(max_length=24,verbose_name='密码')

    通过上述代码,我们定义了一个名叫 Book 的数据表。数据表由以下字段构成书名(title)、出版社(public)、价格(price)、零售价(retail_price),而且对每个字段都做添加了相应的字段属性以及字段选项。

    Django模板加载与响应

    1. 什么是模板

    在 Django 中,模板是可以根据字典数据动态变化的,并且能够根据视图中传递的字典数据动态生成相应的 HTML 网页。Django 中使用 Template 来表示模板,Template 对象定义在 django/template/base.py 文件中,它的构造函数如下所示:

    1. def __init__(self,template_string,origin=None,name=None,engine=None)

    它只有一个必填的参数:字符串表示的模板代码。

    1) 模板的配置

    首先按照BookStore/templates路径创建模板文件夹 templates,在 settings.py 配置文件中有一个 TEMPLATES 变量,如下所示:

    1. TEMPLATES = [
    2. {
    3. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
    4. 'DIRS': [], #指定模板文件的存放路径
    5. 'APP_DIRS': True, #搜索APP里面的所有templates目录
    6. 'OPTIONS': {
    7. 'context_processors': [ #context_processors 用于配置模板上下文处理器
    8. 'django.template.context_processors.debug',
    9. 'django.template.context_processors.request',
    10. 'django.contrib.auth.context_processors.auth',
    11. 'django.contrib.messages.context_processors.messages',
    12. ],
    13. },
    14. },
    15. ]

    其中每一项释义如下所示:

    • BACKEND : Django默认设置,指定了要是用的模板引擎的 Python 路径;
    • DIRS : 一个目录列表,指定模板文件的存放路径,可以是一个或者多个。模板引擎将按照列表中定义的顺序查找模板文件;
    • APP_DIRS : 一个布尔值,默认为 Ture。表示会在安装应用中的 templates 目录中搜索所有模板文件;
    • OPTIONS : 指定额外的选项,不同的模板引擎有着不同的可选参数,例如 context_processors 用于配置模板上下文处理器,在使 RequestContext 时将看到它们的作用。

    2) 修改settings配置文件

    修改 settings.py 文件,设置 TEMPLATES 的 DIRS 值来指定模板的搜索目录为“templates”如下所示:

    1. 'DIRS': [os.path.join(BASE_DIR, 'templates')]

    2. 模板的加载与响应方式

    那么我们如何加载模板并响应给浏览器呢?在前文《Django模板系统》一文,我们已经介绍了一种 render 的方法,其实这里可以使用的方式主要有两种,在本节我们将更加全面的讲解它们。

    方式一:通过 loader 获取模板,通过 HttpResponse 进行响应

    1. from django.template import loader
    2. # 1.通过loader加载模板
    3. t = loader.get_template("模板文件名")
    4. # 2.将t转换成HTML字符串
    5. html = t.render(字典数据)
    6. # 3.用响应对象将转换的字符串内容返回给浏览器
    7. return HttpResponse(html)

    方式二:使用 render 方法直接加载并响应模板

    1. from django.shortcuts import render
    2. return render(request,'模板文件名', 字典数据)

     

     
  • 相关阅读:
    ASP.NET 5 Web Api 集成测试
    EF 7.0 Beta8 实现简单Unit Of Work 模式
    C#与闭包(closure)学习笔记
    异步初探
    BUBI架构之旅【目录】
    【第2期】如何将NameNode和SecondaryNameNode分开不同节点
    【第1期】使用Docker虚拟化技术搭设Hadoop环境
    【第3期】Linux安装数据库oracle 11g
    【第2期】vsftpd的安装与使用
    【第1期】安装Linux服务器(DB主机与ETL主机)
  • 原文地址:https://www.cnblogs.com/hanease/p/16041963.html
Copyright © 2020-2023  润新知