廖雪峰Python3教程---实战day1-day13总结

先放上廖老大的网站:https://www.liaoxuefeng.com/

再放上我的代码(基于Py3.6):https://github.com/leiseraiesecqd/Python3_web


首先是工程文件架构:


廖雪峰Python3教程---实战day1-day13总结_第1张图片
结构图

当然最后我们只完成www部分。


然后分析一下整个博客网站的架构:

基于asyncio(异步io协程,异步编程的一个原则:一旦决定使用异步,则系统每一层都必须是异步,“开弓没有回头箭”。)


廖雪峰Python3教程---实战day1-day13总结_第2张图片

Day2

初步编写app.py,

廖雪峰Python3教程---实战day1-day13总结_第3张图片
实现首页对http的请求

Day3

编写ORM.py,这是个大坑,超级重要,涉及到后台数据库相关。Web App里面有很多地方都要访问数据库。访问数据库需要创建数据库连接、游标对象,然后执行SQL语句,最后处理异常,清理资源。这些访问数据库的代码如果分散到各个函数中,势必无法维护,也不利于代码复用。所以,我们要首先把常用的SELECT、INSERT、UPDATE和DELETE操作用函数封装起来。幸运的是aiomysql为MySQL数据库提供了异步IO的驱动。

1.创建连接池,好处:不必频繁地打开和关闭数据库连接,而是能复用就尽量复用。每个HTTP请求都可以从连接池中直接获取数据库连接。

2.增删改查功能封装,select(sql, args, size=None)函数执行,需要传入SQL语句和SQL参数;execute(sql, args)函数,封装了INSERT、UPDATE、DELETE三个操作,因为这3种SQL的执行都需要相同的参数,以及返回结果数。

3.ORMObject Relational Mapping 对象关系映射(参照day3.py和ORM.py)

有了这个映射关系,我们再操作程序中对象就相当于操作数据库

(1)Field字段类:负责保存(数据库)表的字段名和字段类型

(2)定义五个存储类型类StringField,BooleanField,IntegerField,FloatField,TextField

(3)元类ModelMetaclass,控制Model对象的创建,将具体的子类如User的映射信息读取出来(#构造默认的SELECT, INSERT, UPDATE和DELETE语句)

(4)基类Model,协程操作save()、remove()、update();三个类方法find、findNumber、 findAll。


Day4

完成Model.py,model类表示了博客需要用到的三个数据库中的表:User()、Blog()、Comment()。对应的需要再完成schema.sql文件,完成数据库awesome的创建,包含三个表。

接下来需要测试一下day3、day4的成果,运行test_model.py,向数据库中存入信息,注意的是,参数user,password必须是和自己数据库一致,我的数据库名字就是root,密码为空。运行不出错的话,再打开mysql。查看是否存入了信息:show databases;--->use awesome;--->show tables;--->select * from users; 


Day5

编写web框架,Webframe.py

aiohttp已经是一个Web框架了,为什么我们还需要自己封装一个?原因是从使用者的角度来说,aiohttp相对比较底层,编写一个URL的处理函数需要这么几步:
#第一步,添加协程装饰器

#第二步,对request参数进行操作,以获取相应的参数

#第三步,就是构造Response对象并返回

这些重复的工作可以由框架完成。Web框架的设计是完全从使用者出发,目的是让使用者编写尽可能少的代码。编写简单的函数而非引入request和web.Response还有一个额外的好处,就是可以单独测试,否则,需要模拟一个request才能测试。

1.定义装饰器:get()和post()函数,要把一个函数映射为一个URL处理函数。

2.RequestHandler:从URL函数中分析其需要接收的参数,从request中获取必要的参数,调用URL函数,然后把结果转换为web.Response对象。

最后,在App.py中加入middleware、jinja2模板和自注册的支持:
一个middleware可以改变URL的输入、输出,甚至可以决定不继续处理而直接返回。middleware的用处就在于把通用的功能从每个URL处理函数中拿出来,集中放到一个地方。

它包括logger_factory、auth_factory、data_factory、response_factory,具体功能后期还得探索。


Day6

编写配置文件。完成了orm和webframe之后,一个Web App在运行时都需要读取配置文件,比如数据库的用户名、口令等,在不同的环境中运行时,Web App可以通过读取不同的配置文件来获得正确的配置。config_default.py,config_override.py。


Day7

实现简单的MVC。这里开始涉及到前端知识了,也是个大坑,以后再补。

首先通过Web框架的@get和ORM框架的Model支持,可以很容易地编写一个处理首页URL的函数。注意这个函数在testhandler.py里面,

廖雪峰Python3教程---实战day1-day13总结_第4张图片

然后完成一个test.html放到templates文件下,然后运行App.py,它会调用,testhandler.py里面的index函数。打开浏览器,输入地址:


廖雪峰Python3教程---实战day1-day13总结_第5张图片

至此,一个从后台到前端的过渡我们就解锁了。


Day8

构建前端。基于uikit这个强大的CSS框架,我们来进行开发,下载后放到static下。利用jinjia2的模板还有另一种“继承”方式,实现模板的复用更简单。“继承”模板的方式是通过编写一个“父模板”,在父模板中定义一些可替换的block(块)。然后,编写多个“子模板”,每个子模板都可以只替换父模板定义的block。

首先完成__base__.html编写,然后通过继承,再写一个blogs.html。(均放在templates下)

相应的,再写一个URL处理函数,

廖雪峰Python3教程---实战day1-day13总结_第6张图片

最后考虑一下时间显示的问题,通过jinja2的filter(过滤器),把一个浮点数转换成日期字符。串。在App.py中添加一个datetime_filter。


廖雪峰Python3教程---实战day1-day13总结_第7张图片

点击博客题目,跳转http://127.0.0.1:9000/blog/...,该功能通过blog.html实现单条Blog详细内容界面,post函数/api/blogs/{id}/comments用户评论,提交评论时,通过submit函数执行。

廖雪峰Python3教程---实战day1-day13总结_第8张图片

Day9

编写API,编写API有什么好处呢?由于API就是把Web App的功能全部封装了,所以,通过API操作数据,可以极大地把前端和后端的代码隔离,使得后端代码易于测试,前端代码编写更简单。我们会在test_handlers中完成API的编写。本节进行了一个简单的测试。返回一个数据库的jason值到页面。


Day10

用户注册和登陆功能

注册:注册api(@post('/api/users')方法:api_register_user)+register.html-----创建一个注册页面,让用户填写注册表单,然后,提交数据到注册用户的API。运行App.py,在浏览器中输入http://127.0.0.1:9000/register


廖雪峰Python3教程---实战day1-day13总结_第9张图片

登陆:登陆API(@post('/api/authenticate')方法:authenticate)+计算加密cookie函数(user2cookie)+auth_factory+解密cookie函数(cookie2user)

采用直接读取cookie的方式来验证用户登录,每次用户访问任意URL,都会对cookie进行验证,这种方式的好处是保证服务器处理任意的URL都是无状态的,可以扩展到多台服务器。对于每个URL处理函数,如果我们都去写解析cookie的代码,那会导致代码重复很多次。利用middleware在处理URL之前,把cookie解析出来,并将登录用户绑定到request对象上,这样,后续的URL处理函数就可以直接拿到登录用户。auth_factory在App.py里面,authenticate、user2cookie、cookie2user在test_handler.py里面。


Day11-编写日志创建页

---->@post('/api/blogs'):api_create_blog+manage_blog_edit.html

要编写可维护的前端代码绝非易事。和后端结合的MVC模式已经无法满足复杂页面逻辑的需要了,所以,新的MVVM:Model View ViewModel模式应运而生。在前端页面中,把Model用纯JavaScript对象表示,View是纯HTML,由于Model表示数据,View负责显示,两者做到了最大限度的分离。把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。ViewModel如何编写?需要用JavaScript编写一个通用的ViewModel,这样,就可以复用整个MVVM模型了。好消息是已有许多成熟的MVVM框架,例如AngularJS,KnockoutJS等。我们选择Vue这个简单易用的MVVM框架来实现创建Blog的页面,具体实现细节见廖老大原文。我在实现的时候,没有实现文末说的可以双向绑定,具体原因还未探究。但是MVVM最大的特点就是双向绑定,所以还是需要好好看看的。


廖雪峰Python3教程---实战day1-day13总结_第10张图片

Day 12 - 编写日志列表页

在http://127.0.0.1:9000/manage/      地址下,实现了三个模块,

/users

/comments

/blogs


分页功能:在apis.py中定义一个Page类用于存储分页信息,在test_handler中:

用@get('/api/blogs')方法分页api,用@get('/manage/blogs')显示管理日志的页面。

其中过程:模板页面首先通过API:GET /api/blogs拿到Model,然后,通过Vue初始化MVVM。view的容器是#vm,包含一个table,v-repeat可以把model的blogs变成多行,往Model的blogs数组中增加一个Blog元素,table就神奇地增加了一行;把blogs数组的某个元素删除,table就神奇地减少了一行。所有复杂的Model-View的映射逻辑全部由MVVM框架完成,我们只需要在HTML中写上v-repeat指令,就什么都不用管了。

廖雪峰Python3教程---实战day1-day13总结_第11张图片
管理界面

再来分析一下查看日志功能、“新日志”功能、编辑功能、删除功能:

编辑功能、删除功能:manage_blogs.html,点击编辑,跳转到编辑页面,点击删除,确认后删除。

廖雪峰Python3教程---实战day1-day13总结_第12张图片

编辑页面:manage_blog_edit.html

点保存,提交submit,返回管理界面;点取消,也返回管理界面


廖雪峰Python3教程---实战day1-day13总结_第13张图片
编辑页面


廖雪峰Python3教程---实战day1-day13总结_第14张图片
manage_blog_edit.html

新日志功能:跳转到创建页面http://127.0.0.1:9000/manage/blogs/create



廖雪峰Python3教程---实战day1-day13总结_第15张图片
代码
廖雪峰Python3教程---实战day1-day13总结_第16张图片

同样的分析一下图中评论和用户的实现:

删除评论功能:manage_comments.html+@post('/api/comments/{id}/delete'),实现删除操作。

廖雪峰Python3教程---实战day1-day13总结_第17张图片


查看用户功能:manage_users.html+@get:/api/users


廖雪峰Python3教程---实战day1-day13总结_第18张图片

让我们来总结一下,html所有文件:


廖雪峰Python3教程---实战day1-day13总结_第19张图片

总结一下:get和post方法

Get指令:将()内容输入http://127.0.0.1:9000后面,会显示对应界面;get指令出现在html的herf里面.

Post操作:点击某个按钮,提交信息的时候,系统通过post命令操作 #post出现在html的function中.


补充说明:主函数相当于App.py,每次都运行它。markdown2.py, apis.py 是需要被调用的文件;day3实自己写的没跑痛的orm代码,handler.py就相当于test_handler,这是别人的,当时用来借鉴写test_handlers. 

时间仓促,好多代码没有明白,就是把框架涵盖部分讲了一下。界面跳转还带完善,逻辑还有些问题。前端还好多坑没入,以后有机会好好研究一下。

这个项目重在理解,整个结构,从后端到前台,是怎么一步步建立起来的,这个是重要的。里面每一点都很深,都值得好好研究一下。祝各位和我终有所成!

你可能感兴趣的:(廖雪峰Python3教程---实战day1-day13总结)