Flask Web实战-新闻资讯项目

准备工作

Git相关

创建git项目并clone到自己的电脑,用pycharm打开,做一些修改(忽略文件)。

.pyc 为了让执行python程序导包时更快速而产生的文件
.pyo 链接c语言文件时产生的
.pyd 动态库相关

  • 好习惯:一个阶段的任务完成之后,就提交到git上。
  • 绿色表明新添的内容;蓝色表明修改了的内容。

数据库配置

  • 目的: 为了在项目中用来存储新闻数据以及用户数据的

redis配置

  • 目的: 缓存访问频率高的内容, 存储session信息,图片验证码,短信验证码

session配置

  • 目的: 用来保存用户的登陆信息

CSRFProtect配置

  • 目的: 保护app,防止csrf攻击
  • 校验的请求方式:‘POST’, ‘PUT’, ‘PATCH’, ‘DELETE’

项目介绍

见本地 E:\FlaskWeb\Flask基础资料\项目实战\项目第1部分资料\课件

前后端不分离:前端/客户端看到的东西直接是由后端/服务端安排好,传给对方的。(本项目基于此)
前后端分离:前端/客户端看到的东西是自己进行“绘画”的,后端/服务端仅仅是提供了所需用到的数据(数据是从数据库中取得的)。可以实现后端的接口复用,前端是PC端浏览器也好,还是手机客户端也还,只要该一改相应的框架就可以了。


疑问:一个网页被爬的多了,说明它越有价值?可是为什么在我印象里,有些网站是专门做了避免让自己的网站被爬取呢?矛盾了吧?当然,一定是我哪里没有了解清楚。

技术实现

  • 基于 Python 3.0 + Flask 框架实现
  • 数据存储使用 Redis + MySQL 实现

Redis 内存数据库,主要用来做缓存、存取图片/短信验证码,提高存取效率。MySQL存取持久化数据,如用户登录信息、新闻信息。

  • 第三方扩展:
    • 七牛云:文件存储平台
    • 云通信:短信验证码平台
  • 布署:基于ubuntu 16.04系统(使用阿里云);使用 Gunicorn + Nginx 技术进行布署

项目开发流程

配置文件抽取

  • 目的: 方便今后做扩展、维护, 管理更加高效
  • 操作流程:
  1. 定义config文件
  2. 将Config配置类抽取到config文件中
  3. 提供了3种环境下的配置类信息
  4. 提供了一个config_dict的统一访问入口字典

初始化信息抽取

  • 目的: 将初始化信息抽取到单独的文件,方便做统一的管理
  • 操作流程
  1. 将manger中的初始化信息, 抽取到info的init文件中
  2. 定义了create_app方法, 接收一个config_name参数
  3. 根据config_name加载不同的环境下的配置类信息
  4. 再返回一个完整的app给manager文件

视图函数抽取

  • 目的: 视图函数是用来处理对应业务的,可以有很多,应使用蓝图进行统一管理
  • 操作流程
  1. 创建了modules模块,用来管理所有蓝图的
  2. 在modules底下创建了index包
  3. 在index中创建index_blue蓝图,创建views文件,并使用index_blue装饰视图函数
  4. 在config/create_app方法内部,注册index_blue到app中

循环导包

  • 经典错误——循环导包:
    在这里插入图片描述
  • 解决办法: 在控制台中,查看到底是哪些文件之间产生了循环导包,依次点开所有的文件,只需要想办法断掉其中一环即可
    在这里插入图片描述
    第四个文件是为了寻找redis_store,所以我们可以把第二个文件里的import语句写到redis_import定义语句的后面。

redis存储设置

  • 问题:
    • redis_store创建在了create_app方法内部,外界不能导入使用
    • 在create_app方法外部创建一个空的全局的redis_store,应使用global装饰方法内部的redis_store,声明下面使用的redis_store是全局的那个,而不是新创建的一个局部变量

日志信息集成

  • 目的
    1. 记录用户的行为
    2. 记录并分析软件的问题
    3. 便于给产品经理提供设计依据
  • 操作流程:

Python 自身提供了一个用于记录日志的标准库模块:logging。

  1. 定义好log_file方法,拷贝日志记录方法进来
  2. 在create_app方法中调用即可

日志配置抽取

  • 目的: 为了便于去管理,不同环境下的日志级别
  • 操作流程
    1. 在config配置文件中,给DevelopConfig, ProductConfig设置不同的级别
    2. 在调用create_app方法的时候, 传递对应环境的key值, 只有大于该级别的信息才会被输出
    3. 取出对应的环境下的日志级别, 将日志级别传递到log_file方法中

gitkeep忽略日志文件

  • 目的: 可以让logs空文件夹能够被提交到git仓库

数据库相关

表结构分析

  • 目的: 主要是了解项目中的主要的7张表之间的关系
  • 注意点: 需要查看keynote笔记图

断点调试

注意:如果对一个import语句设置了断点,那么也还要把这一语句要导入的那个包的第一句也设置为断点,要不然进不去,就会停到这里。与之不同的是,如果设置的断点涉及到要访问一个方法,那么是可以自动转到这个方法里的。

数据库迁移

  • 目的: 将模型类迁移成数据库的具体表
  • 操作流程
    1. 导入models,constants文件targeted中
    2. 将create_app中的Sqlalchemy(app),改成两句话
      1. db = Sqlalchemy(), 定义在create_app外部
      2. db.init_app(app), 定义在create_app内部
    3. 在manger.py文件中进行迁移
      1. 导入(import)Manager,Migrate,MigrateCommand
      2. 创建manager对象,管理app
      3. 使用Migrate,关联app,db
      4. 给manager添加一条操作命令
      5. 执行迁移命令(init,migrate,upgrade)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

页面展示相关

静态文件集成

  • 目的: 为了给用户提供访问页面
  • 操作流程: 将static文件夹添加到info里面,然后使用git管理起来

首页显示

  • 目的: 在用户访问首页的时候可以给用户提供一个完整的页面
  • 操作步骤
    1. 在info中,创建templates文件夹
    2. 将static/news中的index.html拖入到templates/news文件夹中
    3. 在访问根路径的时候使用render_template将index.html渲染出来

网站logo显示

  • 目的: 显示网站的一个标识, 显示在title中
  • 注意点
    1. 当浏览器访问每个网站的时候都会自动去请求一个/favicon.ico的接口
    2. 只需要在程序中,写上/favicon.ico的接口,然后返回一张图片即可
    3. 在flask中需要使用current_app.send_static_file(‘文件名’):send_static_file(‘文件1’)会自动去static静态文件夹中寻找文件1

需要清除一下浏览器的cookie,然后关闭浏览器,重新运行程序,重新打开浏览器,才能看到图片加载出来。

图片验证码分析

  • 目的: 为了保证注册、登陆的用户是个真实的用户在操作,就要获取短信验证码
  • 在这里插入图片描述
  • 注意点
    1. 在服务器内部保存图片验证码的时候,前端需要带一个随机字符串(uuid)过来
    2. uuid做为key,图片验证码的值做为value存储

代码不是我们自己写的,就是一个第三方工具类。会创建一个专门的存放第三方工具类的文件夹(utills)。

图片验证码集成

  • 目的: 便于程序调用,生成图片验证码
  • 操作:在info中创建utils包, 将captch导入即可

图片验证码视图函数

  • 目的: 为了方便前端调用生成图片验证码的类,从而获取图片验证码,并进行后续的匹配验证工作

图片验证码去重完善

  • 目的: 不能在服务端存储多份图片,容易导致后端的服务器内存不足
  • 操作流程
    1. 获取参数,cur_id,pre_id
    2. 调用generator_captch()生成图片验证码
    3. 存储图片验证码到redis
    4. 判断是否有上一次图片验证码,如果有则删除
    5. 返回一张图片,并指定图片格式

前端两种情况会去获取验证码:1. 首次点击“注册” 2. 点击图片验证码。后端处理前端这一请求的过程:生成图片验证码–>视图函数获取参数–>保存到redis–>返回图片。

登陆接口

  • 目的: 写出登陆接口,供前端的工程师来调用登陆
  • 操作流程
    1. 获取参数
    2. 校验参数,为空校验
    3. 通过用户手机号,到数据库查询用户对象
    4. 判断用户是否存在
    5. 校验密码是否正确
    6. 将用户的登陆信息保存在session中
    7. 返回响应

首页右上角用户显示

  • 目的: 在首页的右上角显示用户的登陆信息
  • 操作流程
    1. 登陆用户之后,已经将session信息存储到redis了
    2. 当我们刷新首页的时候, 到session中获取了user_id的值
    3. 然后将用户的字典数据,携带到index.html首页展示了

退出用户

  • 目的: 在认证蓝图中编写退出接口
  • 操作流程
    1. 清除session
    2. 返回响应

用户最后登陆时间

  • 目的: 记录用户的登陆时间, 为了方便后期进行用户的活跃统计
  • 工具:
    • database工具,可以在pycharm中链接数据,方便查询等操作
    • structure: 可以快速查看当前文件的结构

自动提交

  • 目的: 在flask通过sqlalchemy的属性配置,让数据库能够自动提交
  • 操作流程
    • 在config的配置文件中,设置sqlalchemy_commit_on_teardown = True
    • 设置好了之后,当数据库的内容改变之后,视图函数在结束的时候就会自动提交了

CSRFProtect校验开启

  • 目的: 在前端当中携带csrf_token, 以便csrf的校验能够通过

  • 校验过程

    • 非表单提交(ajax)
      • 1.在cookie中设置csrf_token (自己做)
      • 2.在请求头中设置csrf_token (自己做)
      • 服务器: 取出二者进行校验
    • 表单提交
      • 在表单设置一个隐藏字段即可
  • CSRFProtect一旦保护好app之后会对如下请求做校验:

    'POST', 'PUT', 'PATCH', 'DELETE'
    

热门新闻排行

未使用过滤器
使用过滤器

(见ipad截屏)

分类数据展示

  • 目的: 在首页的头部展示分类信息
  • 操作流程
    1. 在根路径中查询所有的分类数据
    2. 将分类数据转成字典列表
    3. 携带分类数据渲染页面

用户信息修改和展示

  • 操作流程
    • 如果是get请求:携带用户数据, 渲染页面
    • 如果是post请求:获取参数、校验参数(为空校验)、修改用户的数据、返回响应

用户图片上传(接口)

  • 操作流程
    • 如果是get请求:携带用户数据, 渲染页面
    • 如果是post请求:获取参数、校验参数(为空校验)、上传图片并判断是否上传成功、将图片设置到用户对象、返回响应

图片存储

  1. 自己搭建文件存储系统,比如使用FastDFS。需要自行解决以下两个问题:

    1. 用户A,图片A

      用户B,图片A

      如果用户A,B的图片名字是一样的,但是内容不一样,则后上传的覆盖先上传的

    2. 用户A,图片A

      用户B,图片B

      如果A,B用户上传的图片的名称不一样,但是内容一样,如果保存两份,就浪费存储空间

  2. 使用第三发的工具SDK(如七牛云)。特点:

    1. 可以节省自己的存储空间
    2. 七牛云可以维护我们的图片名字,自动去重

七牛云使用流程:

  1. 用户注册, 创建自己的图片存储空间
  2. 安装扩展包 pip install qiniu
  3. 拷贝官方的代码,到自己的文件中进行封装

密码修改

  • 操作流程
    • 如果是get请求:无需携带用户数据, 直接渲染页面
    • 如果是post请求:获取参数、校验参数(为空校验)、判断老密码是否正确、设置新密码、返回响应

后台管理界面

先添加如下代码,为的是能够手动创建一个用户(而不是注册创建用户)。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

使用命令行的方式创建一个超级管理员:
在这里插入图片描述

管理员登陆

  • 操作流程
    • 如果是GET请求
      • 直接渲染页面
    • 如果是POST请求
      • 获取参数
      • 校验参数,为空校验
      • 根据用户名取出管理员对象
      • 判断管理员是否存在
      • 判断管理员的密码是否正确
      • 管理员的session信息记录
      • 重定向到首页展示

两种页面数据提交方式

  • 表单提交
    • 1.在html文件的表单中,需要设置一个隐藏的csrf_token值 (自己手动设置的)

在这里插入图片描述

  • 2.在cookie中设置一个sessionID (服务器自行设置的)

在这里插入图片描述

服务器校验过程:

  1. 取出表单中的csrf_token(加密的),使用SECRET_KEY解密csrf_token,得到未加密的csrf_token
  2. 根据sessionID解密出服务器空间中的csrf_token(未加密的)
  3. 比较二者是否相等
  • 非表单提交(ajax)
    • 1.在浏览器cookie中设置csrf_token,为了给请求头使用(headers里面的X-CSRFToken)
    • 2.在cookie中设置一个sessionID (服务器自己设置的)

服务器校验过程:

  1. 取出请求中的的csrf_token(加密的),使用SECRET_KEY解密csrf_token,得到未加密的csrf_token
  2. 根据sessionID解密出服务器空间中的csrf_token(未加密的)
  3. 比较二者是否相等

session空间

一个浏览器只有一个session空间,当登陆了管理员账户之后,则打开新闻首页时,就会自动登录成这个管理员的账号。如果又登陆了普通用户,又进入管理员页面时,那么后台管理员的账户就会自动登录上普通用户的,这是不可以的。所以也需要改进:退出登录的时候要把is_admin也清除掉:在这里插入图片描述

后台管理页面

在这里插入图片描述

用户统计

完成五个数据的获取
在这里插入图片描述

用户列表
新闻审核
新闻编辑

管理员可以编辑所有的新闻。

新闻分类(有关ajax数据传送的流程分析)

在这里插入图片描述

分析上图按钮的实现逻辑:
在这里插入图片描述
这个edit选择器在js中得到的监听:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下图红框所在语句表明pop操作(上上图pop.show())会使名为pop_con的类选择器(上图)展示出来:
在这里插入图片描述
在这里插入图片描述
由上图知,点击“确定”后,将会触发confirm类选择器所绑定的事件,即:
在这里插入图片描述
在这里插入图片描述
就是在这个点击事件里,实现了重要逻辑:判断到底是“新增”还是“修改”,然后将数据进行拼接。最后发送了ajax请求给相应的接口文件:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值