Python Django Web典型模块开发实战(txt+pdf+epub+mobi电子书下载)


发布时间:2020-09-01 02:20:35

点击下载

作者:寇雪松

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Python Django Web典型模块开发实战

Python Django Web典型模块开发实战试读:

前言

Django是基于Python编程语言的三大网站框架之一,是一门需要以实践经验来巩固和提高的技术。对于有一定理论和开发基础的Django学习者来说,想要摆脱重章复沓的学习,从而在Django技术领域中更上一层楼,学习实战项目案例绝对大有裨益。与着重于理论知识的教程不同,本书着重于对实际开发中的解决方案进行分析,从而让Django爱好者在学以致用的过程中走得更加自信,对技术的掌握更加牢靠。

在实际应用中,往往是道理都明白,可真要落实到代码开发上时,就会出现各种沟沟坎坎的情况。例如,一个看似很小的问题挡在了开发者的面前,他们也知道这个问题从理论上说是出在哪个环节,但是具体该怎样解决却无法得知。这种情况下,开发者只能选择去网上搜索相关的解决方案,或者去技术社群中提问,但往往收到的答案大多是以理论为主,并不能解决他们所面临的问题。这不仅会耽误开发者的时间,也会极大地影响他们的心态。

本书抛开空泛的理论,对每一个案例的每一个小功能的实现,都通过详细的图文分析和代码实现娓娓道来。读者跟随着本书进行学习,将会亲身体验一次充实的“知其然并知其所以然”的Django进阶实战之旅。本书特色

1.内容翔实,注重实战,通过十多个项目案例带领读者学习

本书内容涵盖了收费API业务模型的开发、网站防爬虫策略、网站违禁词自查系统的搭建、会员系统的搭建、前后端分离项目的上线部署等大大小小十余个项目模块分析,可以基本解决Django学习者从理论到实践过渡过程中经常会遇到的大部分问题。本书内容非常实用,案例的可操作性很强,是一本可以一边学习一边使用的书,书中的不少案例在实际工作中会经常遇到,读者稍加修改就可以应用到自己的项目中。

2.行文诙谐幽默,案例趣味性强,特别适合学习者理解

本书中的每一个案例都是从一个开发者的视角出发对项目进行综合考虑。文中不乏举出了一些诙谐有趣的案例,来形象、生动地阐述一个项目的功能为什么要这样实现,这样实现有什么好处,不这样实现将有可能造成怎样的后果。比如,在分析登录机制的一章中就列举了一个因为登录机制的错误选择而导致验证信息被窃取的例子。通过形象生动的例子,大大降低了读者对新知识的理解难度,让读者可以在流畅的学习过程中更加轻松地获取更多的“干货”。

3.细节清晰,逻辑连贯,保证学习者能够毫不费力地掌握

本书重点着墨于“怎样做”,先力求让读者能够跟着每段代码和每个设置,在自己的计算机上一步一步地将书中所介绍的项目完成一遍。这样可以避免理论方面倒背如流,而真正需要动手敲代码实现时却无从下手的尴尬。这也和本书的讲解理念相吻合,即先让读者知道该怎么做,然后在这个基础上进行原理点拨,这样可以大大提升学习效果。本书内容

第1章 从新浪微博聊起多端应用

假如时至今日,你只会用Django开发PC端的Web项目,还以Python全栈工程师自居的话,相信去哪家公司面试都会被当成入职以后需要再培训很久才能帮上忙的“小白”。一旦在老板心中被贴上了“小白”的标签,再怎么乐观也需要至少半年的时间才能撕掉这个标签吧。这一章我们来聊一聊多端开发。

第2章 用Django REST framework实现豆瓣API应用

几年前,用户想要获取豆瓣数据的API,豆瓣一般都是免费提供的。但是随着近些年数据资产的价值被追捧得越来越高,豆瓣向外提供数据查询的API开始收费,包括电影、图书、音乐等所有类目。本章我们就来开发一套仿豆瓣收费的API项目。

第3章 用Django设计大型电商的类别表

本章我们将和读者一起来构建一个能满足大型电商网站业务需求的类别表。如果问所有使用Django开发的全栈工程师们为什么爱Django,相信会有相当一部分人把Django的ORM摆在所有理由的首位。当某个很“大咖”的编程语言连输出hello world都要新建一个类的时候,利用Django框架都已经可以通过新建一个类直接构建一个高质量的数据表了。本章我们就通过一个电商项目案例来介绍这个话题。

第4章 用Django实现百度开发者认证业务模型

虽然我们经常需要对用户身份进行区分,但又不同于普通用户和付费用户这样的区分方法(当然了,这种区分也会在后面的章节中介绍),而是将用户分为生产者和消费者。本章我们将通过一个类似于百度开发者认证业务的项目模型,让大家能够全面、系统地掌握一个区别于普通网站平台的关键功能的完整搭建流程。

第5章 区块链时代与Token登录

在本章中,我们好好聊一下Django的登录。当然,能够读到本章的读者朋友,想必对于Django框架的了解程度最低也是“登堂入室”了,自然不可能连Django框架自带的登录这么基础的功能都还没掌握(就算还没掌握也不要紧,因为那并不重要)。我们之所以特意以一章的篇幅聊登录,肯定是要聊一些更有趣、又有用的知识,比如Token。

第6章 实现优酷和爱奇艺会员的VIP模式

在本章中,我们来详细地分析一下Django的权限管理,从而可以将读者的权限管理这个知识短板彻底补齐。我们首先会从技术和产品的角度分析权限管理在当前互联网领域的重要程度,然后会新建一个Django项目实例给大家细致入微地讲解权限管理,最后使用Django REST framework的权限管理组件介绍前后端分离项目中如何使用权限管理。

第7章 违禁词自审查功能

常见的违禁词自审查功能分为两种:一种是用户提交想要发表的内容,在经过网站的违禁词自审查检验时,发现内容中包含了一些违禁词,提示用户发表失败,并提示用户内容中有哪些违禁词,要求用户修改内容或者放弃发表,这种违禁词自审查功能大多用于长篇博客、影评、网络小说等篇幅较大的内容审查中;另一种则比较适合评论、发帖等内容篇幅比较短小的应用场景,这种违禁词自审查功能会将检测到的违禁词自动替换为*号。在本章中,我们将会开发一个实际项目,向大家介绍这两种违禁词的自审查功能。

第8章 分析吾爱破解论坛反爬虫机制

近几年,Python语言的人气越来越火,从其他编程语言转Python语言的群体中,因大数据、人工智能和云计算而转学Python的人占了极大一部分;还有一部分人是为了开发爬虫、学习区块链技术、全栈开发和自动化运维等转学Python,其中因开发爬虫而转学Python的群体比例较高。在本章中,我们将会新建一个Django项目,实现非常经典的反爬虫机制——频率限制。

第9章 关于跨域问题的解决办法

一说到跨域,相信只要开发过前后端分离项目的程序员都不会陌生。但是有很大一部分程序员对于跨域问题是知其然而不知其所以然,也就是说会用,但不知道为什么这样用。在本章中,我们来详细地聊一聊跨域这个话题。

第10章 用Django实现支付功能

通过学习前面章节的内容可以看出,开发并运营好一个网站是一笔不小的开销。就算不是以盈利为目的的网站开发者,也有必要学习支付功能的相关知识。在本章中,我们将对国内主流支付平台的业务模式进行分析,并以实际的项目案例演示如何实现支付功能。

第11章 Redis缓存——解决亿万级别的订单涌进

如何通过在开发阶段的设置,让网站服务器在面临巨大压力时能够举重若轻地处理这些数据请求,同时将必要的服务器开销降到最低,这已经成为开发者无法避开的一个问题。在本章中,我们就来解决这个问题,分析目前市场上比较通用的解决方案。

第12章 前后端分离项目上线部署到云服务器

一个项目开发完成后,接下来要做的事就是将项目上线部署到云服务器上。本章我们就来新建一个前后端分离的项目案例,然后将其分别部署到Ubuntu系统上,从而带领大家学习Django项目上线部署到云服务器的相关知识点。本书配套资源获取方式

本书涉及的源代码文件等配套资料需要读者自行下载。请在华章公司的网站www.hzbook.com上搜索到本书,然后单击“资料下载”按钮即可在本书页面上找到“配书资源”下载链接,单击链接即可下载。本书读者对象

·Django自学者;

·具有一定基础的Django开发者;

·其他领域具有Python基础想转型Django开发的人员;

·想要成为全栈开发工程师的前后端程序员;

·Python语言爱好者;

·Web开发项目经理;

·高校相关专业的学生;

·培训机构的相关学员。本书作者

本书由寇雪松编写。感谢在本书编写和出版过程中给予笔者大量帮助的各位编辑!

因作者水平所限,加之写作时间有限,书中可能还存在一些疏漏和不足之处,敬请各位读者批评指正。若您在阅读本书时有疑问,请发电子邮件到hzbook2017@163.com以获取帮助。编著者第1章 从新浪微博聊起多端应用

当人们听到“新浪”,脑海里第一个浮现的关联词是“新浪微博”,而不是“新浪博客”的时候,互联网已经发展到了多端应用的时代。如果一个互联网公司的业务数据,还只能通过PC端访问,那么可以丝毫不危言耸听地说,这家互联网公司不论经营的业务是什么,都很难在这个时代有所建树。

同样地,假如时至今日,一个互联网开发者只会用Django开发PC端的Web项目,还以Python全栈工程师自居的话,相信他去哪家公司面试,都会被当成入职以后需要再培训很久,才能进入工作的“小白”,一旦在老板心中被贴上“小白”的标签,再怎么乐观,也需要半年的时间来撕掉吧?

其实“小白”跟“老鸟”相差的,不就是“老鸟”比“小白”多了解了一些知识点吗?只不过这些知识点是实际项目中必然会用到,而学校和培训班却很少提及的。一般的程序员,只能在年复一年的工作经验中获得这些知识点。幸运的是,本书里满满的都是这样的知识点,从本章开始,向一只“老鸟”蜕变吧。1.1 AOP面对切面编程思想

这一节,我们来介绍多端应用的基础编程思想。站在一个项目架构者的角度,对项目的宏观布局做到胸有成竹是一项必备技能。其实多端应用的概念刚开始火起来的时候,Python全栈开发还方兴未艾(至少不像近些年这么热),当时PHP正如日中天,AOP就被广泛应用。想要与资深的Web开发人员侃侃而谈,那么AOP是一个绝佳的谈资。

AOP(Aspect Oriented Programming,面向切面编程),如果要长篇大论地介绍其最早是怎么来的,是通过多少复杂的机制实现的,那将是晦涩难懂的原理,下面举一个例子来跟大家解释什么是AOP。

假如文轩和阿福家里各有一棵苹果树,今天市场上苹果很畅销,文轩和阿福都很开心,因为他们可以摘苹果去卖钱。但是第二天市场上桃子变得畅销了,苹果滞销了,文轩不开心了,因为他只有一颗苹果树,他的苹果树只能结苹果,长不出桃子来。

但是阿福依然很开心,因为他在他的苹果树上嫁接了一根桃枝,当天就长出了很多桃子,又卖了很多钱。第三天市场上橘子变得畅销了,文轩依然不开心,因为他只有苹果;阿福依然很开心,因为他在苹果树上又嫁接了一根橘子枝。第四天阿福在苹果树上嫁接了一根梨枝,第五天嫁接了一根西瓜枝,第六天嫁接了一根巧克力枝……阿福的做法就是AOP,阿福的苹果树就是一个基于面对切面编程思想架构的Web。

AOP在软件架构中的应用非常广泛,是一种如果使用AOP架构最好,如果不使用AOP也行,至多就是耦合度高点儿的应用。但是在Web项目开发中,特别是进入移动互联网时代以来,基于AOP思想,对项目进行前后端分离的基本架构,已经成为了一种必须要做的事情。2012年以前,新浪的CTO如果跟CEO说:“新浪微博只能从PC端访问。”那么并没有什么问题,但是,如果今天,新浪的CTO跟CEO说:“新浪微博只能从PC端访问。”,那还不如直接说“世界那么大,我想去看看。”显得更文艺一点。

2017年12月,胡润研究院发布了《2017胡润大中华区独角兽指数》,榜单上的所有“独角兽”公司,都可以通过PC端和移动端进行业务访问,这个结果其实是可预料的。是的,现在多端应用可以说是绝大部分公司的业务标配,身为一个程序员,必须要有一棵能长巧克力的苹果树。1.2 Django的前后端分离

相信对Django有所了解的读者都知道,Django的普通项目是基于MVT模式(Model View Template)开发的,而Django的前后端分离项目则是基于MVVM模式(Model View ViewModel)开发的,解耦得更彻底,彻底到前后端分离了,甚至可以说分离成了两个项目。

Django前后端分离项目原理:后端遵循restful规范开发API,与前端进行数据交互,实现多端应用。1.2.1 什么是API

API作为一个互联网行业的术语,很少被直接翻译过来,因为在中文中并没有一个对应的词汇可以完全表达其含义,如果强行翻译,可以被翻译为数据接口,但显然这个翻译并不准确。举个现实中的例子,比如购房网上面有全国房屋买卖的交易数据,万达公司在需要一些房屋交易数据来作为参考投产项目时,如果自己去做社会调研,费时、费力,非常不合算,所以万达公司每年都要向购房网支付数百万元来购买这些交易数据。大家是否考虑过,这一笔交易是以怎样的方式进行的呢?

所谓的一手交钱一手交货,交钱的流程比较简单,只要万达公司将资金汇给购房网就可以了,但是购房网是怎样将全国房屋买卖的交易数据交给万达公司呢?难道是直接将数据库复制给万达公司一份吗?这显然不可能。购房网是将一些API和权限交给万达公司的技术人员,万达公司的技术人员就可以通过调用这些API获取到他们所需要的交易数据。当然,API是一个广义的概念,除了可以通过调用API获取到数据资源外,还可以通过API提供和获取技术服务,在无数的SDK(软件开发包)中都有所体现。在本章中,我们主要是通过API获取数据。

在业内编写这类API,不论是使用什么编程语言,都需要遵循RESTful规范,当然这是众所周知的事情。1.2.2 RESTful规范——如何写API

API接口应该如何写?API跟URL有什么不同?这绝对是不可以被忽略的问题,如果API写得乱七八糟,很有可能会失去负责前端开发的同事的信任。将API写得“高大上”,也是一名开发者工匠精神的一种体现。下面来介绍如何写API。(1)如果是对同一个表进行数据操作(增、删、改、查),应该使用一条API,然后根据method的不同,进行不同的操作。GET/POST/PUT/DELETE/PATCH(2)面向资源编程,通过API提交的参数最好是名词,比如name,尽量少用动词。http://www.abc.com/name(3)体现版本,在API中加入像v1、v2这样的版本代号:http://www.abc.com/v1/namehttp://www.abc.com/v2/name(4)体现API,让使用者一眼能看出这是API而不是URL,应该在API中加入提示:http://www.abc.com/api/v1/namehttp://www.abc.com/api/v2/name(5)使用HTTPS,这一项原本是为了安全考虑,但是随着国内外互联网环境对安全性越来越重视,谷歌浏览器对所有不是HTTPS请求的链接全都会提示用户此链接为不安全链接,腾讯等平台也对小程序等产品强制要求使用HTTPS协议。不过,好在国内许多提供云服务的公司,像腾讯云、阿里云等,都提供免费的SSL证书,供开发者去申请。https://www.abc.com/api/v1/namehttps://www.abc.com/api/v2/name(6)响应式设置状态码,例如,200和201代表操作成功,403代表权限不够,404代表没有指定资源,500代表运行时发现代码逻辑错误等。return HttpResponse('adgbag',status=300)(7)API的参数中加入筛选条件参数,也可以理解为获取资源优先选择GET的方式。https://www.abc.com/api/v2/name?page=1&size=10(8)返回值的规范,不同的method操作成功后,后端应该响应的返回值如下:https://www.abc.com/api/v1/name

不同的提交方式代表对数据进行不同的操作:

·GET:所有列表。

·POST:新增的数据。https://www.abc.com/api/v1/name/1

·GET:单条数据。

·PUT:更新,返回更新的数据。

·PATCH:局部更新,返回更新的数据。

·DELETE:删除,返回空文档。(9)返回错误信息,应该加入错误代号code,让用户能直接看出是哪种类型的错误。ret { code:1000, data:{ {'id':1,'title':'lala'} }}(10)返回的详细信息,应该以字典的形式放在data中。ret { code:1000, data:{ {'id':1,'title':'lala','detail':http://www.……} }}

RESTful规范是业内约定俗成的规范,并不是技术上定义的公式,在实际生产使用中,大家还是要根据业务灵活运用。1.2.3 Django REST framework简介

在Python的Web业内广为流传一句话“使用Python进行Web全栈开发者必会Django,使用Django开发前后端分离项目者必会Django REST framework”。使用Python进行Web全栈开发的框架,主流的就有4个,但是大家除了使用Django以外,其他的都很少使用。Django本身也拥有一些模块,可以用于完成前后端分离项目的需求,但是大家除了使用Django REST framework以外,也很少使用其他模块。

所以但愿读者在读到此处之前,没有浪费更多的时间去学习那些很少会被用到的知识。Django REST framework之所以能够拥有如此超然的地位,源于其将Python语言特有的一些优势发挥得淋漓尽致,虽然其中也有可以再完善的空间,但可以毫不夸张地说,如果可以将Django REST framework的10个常用组件融会贯通,那么使用Django开发前后端分离的项目中有可能遇到的绝大部分需求,都能得到高效的解决。

Django REST framework的10个常用组件如下:

·权限组件;

·认证组件;

·访问频率限制组件;

·序列化组件;

·路由组件;

·视图组件;

·分页组件;

·解析器组件;

·渲染器组件;

·版本组件。

Django REST framework官方文档的地址是https://www.django-rest-framework.org/。

新建一个Django项目,命名为book,作为贯穿本书的演示项目。选择PyCharm作为开发工具,在新建目录时,新建App命名为users。第2章 用Django REST framework实现豆瓣API应用

活跃在互联网上的年轻人中,不论是文艺青年还是非文艺青年,可能都会去逛豆瓣网(以后简称为豆瓣),因此大家对豆瓣并不陌生。豆瓣上多年以来囤积的海量数据,对于无数与文艺相关的项目是非常重要的内容。比如想要开发一个面向喜欢重金属音乐的用户群体的音乐推荐软件,就需要获取豆瓣中重金属类目下的音乐数据信息,以此了解哪些音乐评分较高。

几年前,豆瓣这些数据的API,都是免费提供给广大开发者的,但是随着近些年数据资产的价值越来越被重视,豆瓣向外提供数据查询的API开始收费,包括电影、图书、音乐等所有类目。

开发者想要获得豆瓣上的数据,需要向豆瓣付费,才可以有权限调用相关的API,而本章就是开发一个这样的业务模型。2.1 豆瓣API功能介绍

豆瓣图书的API功能原理是用户通过输入图书的ISBN号(书号)、书名、作者、出版社等部分信息,就可获取到该图书在豆瓣上的所有信息。当然,API中除了要包含检索信息之外,还要包含开发者的apikey,用来记录开发者访问API的次数,以此向开发者收费。目前豆瓣图书的API是0.3元/100次。2.2 Django REST framework序列化

序列化(Serialization)是指将对象的状态信息转换为可以存储或传输形式的过程。在客户端与服务端传输的数据形式主要分为两种:XML和JSON。在Django中的序列化就是指将对象状态的信息转换为JSON数据,以达到将数据信息传送给前端的目的。

序列化是开发API不可缺少的一个环节,Django本身也有一套做序列化的方案,这个方案可以说已经做得很好了,但是若跟Django REST framework相比,还是不够极致,速度不够快。2.2.1 Postman的使用

Postman是一款非常流行的API调试工具,其使用简单、方便,而且功能强大。

通过Postman可以便捷地向API发送GET、POST、PUT和DELETE请求,几乎是资深或者伪资深开发人员调试API的首选。当然,这并不是Postman在开发领域如此受欢迎的唯一理由。Postman最早是以Chrome浏览器插件的形式存在,可以从Chrome应用商店搜索、下载并安装,后来因为一些原因,Chrome应用商店在国内无法访问,2018年Postman停止了对Chrome浏览器的支持,提供了独立安装包,不再依赖Chrome,同时支持Linux、Windows和Mac OS系统。

测试人员做接口测试会有更多选择,例如Jmeter和soapUI等,因为测试人员就是完成产品的测试,而开发人员不需要有更多的选择,毕竟开发人员是创新者、创造者。Postman的下载地址是https://www.getpostman.com/apps。2.2.2 用serializers.Serializer方式序列化

还记得我们在第1章中新建的Django项目book吗?下面我们来一起在这个项目中一步一步地通过Serializer序列化组件,完成豆瓣API核心功能的开发。(1)打开项目book。(2)安装Django REST framework及其依赖包markdown和django-filter。命令如下:pip install djangorestframework markdown django-filter(3)在settings中注册,代码如下:INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contentTypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'users.apps.UsersConfig', 'rest_framework'](4)设计users的models.py,重构用户表UserProfile,增加字段APIkey和money。当然,为了演示核心功能,可以建立一张最简单的表,大家可以根据个人喜好增加一些业务字段来丰富项目功能。from django.db import modelsfrom django.contrib.auth.models import AbstractUser# Create your models here.class UserProfile(AbstractUser): """ 用户 """ APIkey=models.CharField(max_length=30,verbose_name='APIkey',default='abcdefghigklmn') money=models.IntegerField(default=10,verbose_name='余额') class Meta: verbose_name='用户' verbose_name_plural = verbose_name def __str__(self): return self.username(5)在settings中配置用户表的继承代码:AUTH_USER_MODEL='users.UserProfile'(6)在users的models.py文件中新建书籍信息表book,为了演示方便,我们姑且将作者字段并入书籍信息表,读者在实际项目中可根据业务模式灵活设计数据表model:from datetime import datetimefrom django.db import modelsclass Book(models.Model): """ 书籍信息 """ title=models.CharField(max_length=30,verbose_name='书名',default='') isbn=models.CharField(max_length=30,verbose_name='isbn',default='') author=models.CharField(max_length=20,verbose_name='作者',default='') publish=models.CharField(max_length=30,verbose_name='出版社',default='') rate=models.FloatField(default=0,verbose_name='豆瓣评分') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间') class Meta: verbose_name='书籍信息' verbose_name_plural = verbose_name def __str__(self): return self.title(7)执行数据更新命令:python manage.py makemigrationspython manage.py migrate(8)建立一个超级用户,用户名为admin,邮箱为1@1.com,密码为admin1234。python manage.py createsuperuserUsername: admin邮箱: 1@1.comPassword:Password (again):(9)通过PyCharm的Databases操作面板,直接在book表内增加一条记录,title为一个书名,isbn为777777,author为一个作者,publish为一个出版社,rate为6.6,add_time为154087130331。(10)准备工作已经完成,接下来是我们的“正片”开始啦。在users目录下新建py文件serializers,将序列化的类代码写入其中:from rest_framework import serializersfrom .models import UserProfile,Bookclass BookSerializer(serializers.Serializer): title=serializers.CharField(required=True,max_length=100) isbn=serializers.CharField(required=True,max_length=100) author=serializers.CharField(required=True,max_length=100) publish=serializers.CharField(required=True,max_length=100) rate=serializers.FloatField(default=0)(11)在users/views中编写视图代码:from .serializers import BookSerializerfrom rest_framework.views import APIViewfrom rest_framework.response import Responsefrom .models import UserProfile,Bookclass BookAPIView1(APIView): """ 使用Serializer """ def get(self, request, format=None): APIKey=self.request.query_params.get("apikey", 0) developer=UserProfile.objects.filter(APIkey=APIKey).first() if developer: balance=developer.money if balance>0: isbn = self.request.query_params.get("isbn", 0) books = Book.objects.filter(isbn=int(isbn)) books_serializer = BookSerializer(books, many=True) developer.money-=1 developer.save() return Response(books_serializer.data) else: return Response("兄弟,又到了需要充钱的时候!好开心啊!") else: return Response("查无此人啊")(12)在urls中配置路由如下:from django.contrib import adminfrom django.urls import pathfrom users.views import BookAPIView1urlpatterns = [ path('admin/', admin.site.urls), path('apibook1/',BookAPIView1.as_view(),name='book1'),]

至此,我们可以运行book项目,使用Postman访问API来测试一下啦。我们用Postman的GET方式访问API:http://127.0.0.1:8000/apibook1/?apikey=abcdefghigklmn&isbn=777777

我们获得了想要的JSON数据:[ { "title": "一个书名", "isbn": "777777", "author": "一个作者", "publish": "一个出版社", "rate": 6.6 }]

然后到数据库中查看一下,发现用户admin的money被减去了1,变成了9。当我们用Postman故意填错apikey时,访问:http://127.0.0.1:8000/apibook1/?apikey=abcdefghigklmn33&isbn=777777

API返回的数据为:"查无此人啊"

当我们连续访问10次:http://127.0.0.1:8000/apibook1/?apikey=abcdefghigklmn&isbn=777777

API返回的数据为:"兄弟,又到了需要充钱的时候!好开心啊!"

至此,一个简单的模仿豆瓣图书API的功能就实现了。在实际的项目中,这样的实现方式虽然原理很清晰,但是存在着很明显的短板,比如被查询的表的字段不可能只有几个,我们在真正调用豆瓣图书API的时候就会发现,即使只查询一本书的信息,由于有很多的字段和外键字段,返回的数据量也会非常大。如果使用Serializer进行序列化,那么工作量实在太大,严重影响了开发效率。

所以,这里使用Serializer进行序列化,目的是让大家通过这种序列化方式更加轻松地理解Django REST framework的序列化原理。在实际生产环境中,更加被广泛应用的序列化方式是采用了Django REST framework的ModelSerializer。2.2.3 用serializers.ModelSerializer方式序列化

在上一节中,我们通过使用Django REST framework的Serializer序列化,实现了一个模仿豆瓣图书API的功能,在这一节,我们将要使用Django REST framework的ModelSerializer来实现这个功能。因为都是在book项目中,所以上一节中介绍的很多步骤我们没有必要重复。我们现在要做的,首先是到数据库中的UserProfile表中,将用户admin的money从0修改回10,不然API只能返回提醒充值的数据。

在users/Serializer.py中,写book的ModelSerializer序列化类:from rest_framework import serializersfrom .models import UserProfile,Bookclass BookModelSerializer(serializers.ModelSerializer): class Meta: model = Book fields="__all__" #将整个表的所有字段都序列化

在users/views.py中,编写基于BookModelSerializer的图书API视图类:BookModelSerializer的图书API视图类:from .serializers import BookModelSerializerfrom rest_framework.views import APIViewfrom rest_framework.response import Responsefrom .models import UserProfile,Bookclass BookAPIView2(APIView): """ 使用ModelSerializer """ def get(self, request, format=None): APIKey=self.request.query_params.get("apikey", 0) developer=UserProfile.objects.filter(APIkey=APIKey).first() if developer: balance=developer.money if balance>0: isbn = self.request.query_params.get("isbn", 0) books = Book.objects.filter(isbn=int(isbn)) books_serializer = BookModelSerializer(books, many=True) developer.money-=1 developer.save() return Response(books_serializer.data) else: return Response("兄弟,又到了需要充钱的时候!好开心啊!") else: return Response("查无此人啊")

注意:使用ModelSerializer序列化对应的视图类与使用Serializer进行序列化对应的视图类,除了序列化的方式不同,其他的代码都是相同的。

在urls中配置路由代码:from django.contrib import adminfrom django.urls import pathfrom users.views import BookAPIView1,BookAPIView2urlpatterns = [ path('admin/', admin.site.urls), path('apibook1/',BookAPIView1.as_view(),name='book1'), path('apibook2/',BookAPIView2.as_view(),name='book2'),]

使用Postman对API进行测试,用GET的方式访问:http://127.0.0.1:8000/apibook2/?apikey=abcdefghigklmn&isbn=777777

返回书籍所有的字段数据:[ { "id": 1, "title": "一个书名", "isbn": "777777", "author": "一个作者", "publish": "一个出版社", "rate": 6.6, "add_time": null }]

注意:这里的add_time字段为null,是因为这个项目使用了Django默认的db.sqlite3数据库。由于db.sqlite3在存储时间字段的时候,是以时间戳的格式保存的,所以直接使用Django REST framework的Serializer进行序列化失败。在实际项目中,我们会选择MySQL等主流数据库,就不会出现这种情况了。

可以看出,对于一条有很多字段的数据记录来说,使用ModelSerializer的序列化方式,可以一句话将所有字段序列化,非常方便。当然,ModelSerializer也可以像Serializer一样对某几个特定字段进行序列化,写法也很简单,只需要对原本的BookModelSerializer修改一行代码:class BookModelSerializer(serializers.ModelSerializer): class Meta: model = Book # fields="__all__" #将整个表的所有字段都序列化 fields = ('title', 'isbn', 'author') #指定序列化某些字段

使用Postman对API进行测试,用GET的方式访问:http://127.0.0.1:8000/apibook2/?apikey=abcdefghigklmn&isbn=777777

返回的数据就成了:[ { "title": "一个书名", "isbn": "777777", "author": "一个作者" }]

至此,我们对Django REST framework的两种序列化方式做一个总结:Serializer和ModelSerializer两种序列化方式中,前者比较容易理解,适用于新手;后者则在商业项目中被使用的更多,在实际开发中建议大家多使用后者。

记得笔者初学Django REST framework时,一直很困惑于用哪种序列化方式更好。因为许多教材中都将Django REST framework的Serializer和ModelSerializer,与Django的Form和ModelForm做对比,虽然二者相似,在优劣选择上却是不同的。Form虽然没有ModelForm效率高,但是ModelForm的使用增加了项目的耦合度,不符合项目解耦原则,所以Form比ModelForm更优(除了字段量过大的情况);而ModelSerializer有Serializer所有的优点,同时并没有比Serializer明显的不足之外,所以ModelSerializer比Serializer更优。2.3 Django REST framework视图三层封装

其实,Django REST framework中最令人困惑的并不是Serializer与ModelSerializer的选择,而是三层封装的视图使用哪种好?到底应该怎样选择?视图层层封装,层层嵌套,令人混乱不堪,再加上版本更替,许多教程与实际项目中的演示对不上号,学习起来更是晦涩难懂。

最无奈的是,就算硬着头皮将文档教程“啃”下来,但依然困惑于实现一个功能,到底应该封装几层,使用哪种视图方式,根本不敢贸然选择,犹豫不决之间又浪费了许多时间。因此业内有十个抛弃Django REST framework的人里九个是因为视图封装之说。我们将会在下一节聊一聊视图的三层封装,如果你也是一个对Django REST framework视图的三层封装如鲠在喉的程序员,可要打起精神来。2.3.1 用mixins.ListModelMixin+GenericAPIView的方式实现视图封装

在users/views.py中,使用mixins.ListModelMixin+GenericAPIView编写基于Book ModelSerializer的图书API视图类。代码如下:from .serializers import BookModelSerializerfrom rest_framework.response import Responsefrom .models import UserProfile,Bookfrom rest_framework import mixinsfrom rest_framework import genericsookMixinView1(mixins.ListModelMixin,generics.GenericAPIView): queryset=Book.objects.all() serializer_class = BookModelSerializer def get(self,request,*args,**kwargs): #如果这里不加get函数,代表默认不 支持get访问这个api,所以必须加上 APIKey = self.request.query_params.get("apikey", 0) developer = UserProfile.objects.filter(APIkey=APIKey).first() if developer: balance=developer.money if balance>0: isbn = self.request.query_params.get("isbn", 0) developer.money -= 1 developer.save() self.queryset = Book.objects.filter(isbn=int(isbn)) return self.list(request, *args, **kwargs) else: return Response("兄弟,又到了需要充钱的时候!好开心啊!") else: return Response("查无此人啊")

在urls中配置路由代码如下:from django.contrib import adminfrom django.urls import pathfrom users.views import BookAPIView1,BookAPIView2from users.views import BookMixinView1urlpatterns = [ path('admin/', admin.site.urls), path('apibook1/',BookAPIView1.as_view(),name='book1'), path('apibook2/',BookAPIView2.as_view(),name='book2'), path('apibook3/',BookMixinView1.as_view(),name='book3'),]

这时,我们再使用Postman对API进行测试,用GET的方式访问:http://127.0.0.1:8000/apibook3/?apikey=abcdefghigklmn&isbn=777777

我们获得了跟使用APIView编写的API视图同样的效果,也获得了以下数据:[ { "title": "一个书名", "isbn": "777777", "author": "一个作者" }]2.3.2 用generics.ListAPIView的方式实现视图封装

在users/views.py中,使用generics.ListAPIView编写基于BookModelSerializer的图书API视图类,代码如下:from .serializers import BookModelSerializerfrom rest_framework.response import Responsefrom .models import UserProfile,Bookfrom rest_framework import mixinsfrom rest_framework import genericsclass BookMixinView2(generics.ListAPIView): queryset = Book.objects.all() serializer_class = BookModelSerializer def get(self,request,*args,**kwargs): APIKey = self.request.query_params.get("apikey", 0) developer = UserProfile.objects.filter(APIkey=APIKey).first() if developer: balance=developer.money if balance>0: isbn = self.request.query_params.get("isbn", 0) developer.money -= 1 developer.save() self.queryset = Book.objects.filter(isbn=int(isbn)) return self.list(request, *args, **kwargs) else: return Response("兄弟,又到了需要充钱的时候!好开心啊!") else: return Response("查无此人啊")

在urls中配置路由代码:from django.contrib import adminfrom django.urls import pathfrom users.views import BookAPIView1,BookAPIView2from users.views import BookMixinView1,BookMixinView2urlpatterns = [ path('admin/', admin.site.urls), path('apibook1/',BookAPIView1.as_view(),name='book1'), path('apibook2/',BookAPIView2.as_view(),name='book2'), path('apibook3/',BookMixinView1.as_view(),name='book3'), path('apibook4/',BookMixinView2.as_view(),name='book4'),]

使用Postman对API进行测试,用GET的方式访问:http://127.0.0.1:8000/apibook4/?apikey=abcdefghigklmn&isbn=777777

我们获得了跟使用APIView编写的API视图同样的效果,也获得了以下数据:[ { "title": "一个书名", "isbn": "777777", "author": "一个作者" }]

注意:使用mixins.ListModelMixin+generics.GenericAPIView对APIView进行一次封装,至少需要加一个get函数:def get(self,request,*args,**kwargs): return self.list(request,*args,**kwargs)

而使用generics.ListAPIView则可以不用加这个函数,因为generics.ListAPIView相对于mixins.ListModelMixin+generics.GenericAPIView而言,所谓的封装,就是封装了一个get函数罢了。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载