Flask狼书笔记 | 09_图片社交网站 - 大型项目的架构与需求(1)

简介: 9 图片社交网站本章新涉及的Python包:Flask-Dropzone, Pillow, Flask-Avatars, Whoosh, Flask-Whooshee。9.1 项目组织架构1、功能式架构

9 图片社交网站

本章新涉及的Python包:Flask-Dropzone, Pillow, Flask-Avatars, Whoosh, Flask-Whooshee

9.1 项目组织架构

1、功能式架构

在该架构中,程序包由各个代表程序组件(功能)的子包组成,如 blueprints(蓝本),froms(表单),templates(模板),models(模型)等。这也是前一章个人博客项目中,所采用的架构方式。

2、分区式架构

在分区式架构中,程序被按照自身的板块分成不同的子包,如 front(前台),auth(用户),dashboard(后台)。这种分类自然决定了每一个子包都对应着一个蓝本。

myapp/
  dashboard/
    - __init__.py
    - views.py
    - forms.py
    templates/
    static/
  front/
    ...
  auth/
    ...
  __init__.py

也许上面两种架构的描述会让你有些混淆,你也可以这样理解:功能式架构将相似的代码组织在一起,而分区式架构将同一块业务组织在一起。

3、混合式架构

即不按照常规的分类来组织。比如在分区式架构的基础上,使各个蓝本公用程序包根目录下的模板文件夹和静态文件夹。

Flask并不限制你组织项目的方式,你可以根据自己程序的特点自由选择。

9.2 编写程序骨架

1、可能用到的资源

  • 在线图片占位服务:如基于Unspalsh的Lorem Picsum。在程序开发的过程种,可以生成不同的用于占位的图片。
  • 开源图标集:如Font AwesomeMaterial Design IconsOctions等,还有与Bootstrap集成良好的Iconic。(p308)

2、缓存破坏

如果你总是向同一个url发起请求,而实际获取不同的返回结果。如

<img src="https://picsum.photos/800/?random">

但浏览器可能会使用缓存的响应。为了处理这个问题,你可以再加一个无意义但是会变化的查询字符串

9.3 高级用户认证

注册一个账号通常包含这样的步骤:填写注册信息、接收注册邮件、通过单击验证链接来确认账号。

1、验证邮箱地址

验证链接是一个类似/confirm/的URL,后面是一个传递给视图函数的变量,即一个用来验证用户身份的令牌。用户点击链接使服务器收到请求后,会解析令牌以获得存储再其中的用户 id,然后执行确认的操作。


因为令牌经过签名,所以可以确保其不会被篡改。


问题:“签名”是原理是什么?

  • 扩展Flask-Security:可以简化用户认证的实现过程。

9.4 基于用户角色的权限管理

在一些简单的程序中,通常只有两种用户角色:普通用户和管理员,所以在角色和权限上并不需要花费太多的功夫。但在一些复杂的程序中,你可能会有更丰富的角色,如被封禁的用户、被锁定的用户等等。每一种角色又有着不同的权限,角色和权限之间是多对多的关系

roles_permissions_map = {
  'Locked': ['Follow', 'Collect'],
    'User': ['Follow', 'Collect', 'Comment'],
    ...
}

在程序开始时,你需要提供一个方法初始化角色和权限的关系,即将该关系写入数据库中。然后,你可以编写权限验证装饰器,附加到视图函数前,使具有响应权限的用户才能访问该视图函数。

9.5 使用Flask-Dropzone优化文件上传

使用普通表单进行文件上传时,如果同时上传多个文件,用户只能在一个毫无变化的页面面前苦苦等待。为了优化用户体验,我们可以显示一个包含上传文件的列表,展示文件上传的进度。Flask-Dropzone扩展可以帮助我们做到这件事情。


Flask-Dropzone提供了基本配置、内置的文件类型配置、以及错误消息的配置。(p326)


该扩展还内置了对于CSRFProtect扩展的支持,可以在上传文件表单中自动添加csrf令牌隐藏字段,并在处理文件上传请求时自动验证csrf令牌。

DROPZONE_ENABLE_CSRF = True

载。有可以分别使用dropzone.load_css()和dropzone.load_js()方法从CDN加载静态资源。


保存图片


Flask-dropzone扩展承担了渲染界面、接收文件和验证工作,而保存图片需要我们自己完成。图片的保存包含两个更具体的操作:


将图片文件保存到文件系统

  1. 将图片信息保存到数据库

Flask-Dropzone还扩展内置了一个生成随机文件名的函数:

from flask_dropzone import random_filename
filename = random_filename(f.filename) # 从原文件名生成新的文件名

Dropzone.js(Flask-Dropzone的静态资源)通过AJAX请求发送文件,每个文件一个请求,因此在完成上传后并不会将网页的控制权交给Flask的视图函数。一个不错的做法是提供一个按钮,让用户自行控制。你也可以配置键DROPZONE-DEDIRECT_VIEW在完成上传后自动跳转到指定页面。


图片裁剪


网页中大量体积较大的图片会延缓网页的加载速度。一种可行的做法是,为一张图片保存同时保存多个不同大小的副本,在不同的场景下,使用不同大小的图片。(p333)

9.6 使用Flask-Avatars处理用户头像

在用户还没有自定义头像时,可以为用户提供一个默认头像。Flask-Avatars在模板中开放了avatars类:

<img src="{{ avatars.defualt() }}">

默认头像太过简陋,你可以在注册时为用户生成随机的头像(像素样式)。配置如下:

AVATARS_SAVE_PATH = os.path.join(ALBUMY_UPLOAD_PATH, 'avatars')
AVATARS_SIZE_TUPLE = (30, 100, 200) # 同时生成三种尺寸的头像

然后就可以在User模型中添加生成头像的代码。扩展会自动生成和保存图像到文件系统中,你只需要再将文件的信息保存到数据库中即可。

from flask_avatars import Identicon
avatar = Identicon()
filenames = avatar.generate(text=self.username) # 可以通过一些参数进行更加丰富的配置(p336)

你可以创建一个类似Flask内置的static视图的视图函数,以方便在模板中通过url_for()函数访问图片文件。(p337)

9.7 图片展示与管理

在用户的主页,可以展示图片的列表。如果你的用户对象使用location字段存储城市信息,你还可以将这个字符渲染为链接,通过将城市值拼接到Google地图的查询链接后,点击可以跳转到Gootle地图显示相关结果。

<!-- target="_blank" : 在新窗口打开链接 -->
<a href="https://www.google.com/maps?q={{ user.location }}" target="_blank"> 
  {{ user.location | truncate(20) }}
</a>

truncate过滤器可以将字符截取到指定长度后显示。


在图片标签的外部添加一个标签,可以用于访问图片的详情页面(即实现通过点击图片进行页面跳转)。(p340)

删除确定模态框

删除图片时,相比浏览器默认的确认窗口,使用模态框可以使页面的样式显得更加一致。如果通过jinja2的for循环,对每个删除按钮都生成一个模态框,最终的页面中将包含大量的模态框代码,但这些代码大部分通常都不会被使用。更合理的方式是使所有的删除按钮都指向同一个模态框,

{# 删除按钮 #}
<a class="btn" data-tggle="modal" data-target="#confirm-delete" data-href="...">Delete</a>
{# 模态框 #}
<div class="modal fade" id="confirm-delete" ...></div>

然后通过JavaScript代码,监听模态框的打开事件。(p345)

$('#confirm-delete').on('show.bs.modal', function(e){
    $('.delete-form').attr('action', $(e.relatedTarget).data('href'));
})

编辑图片描述

常用的一个做法是添加一个编辑按钮,在用户单击时跳转到对应的编辑页面,在完成编辑后再跳转回来。但,更好的方式是让用户直接在当前页面编辑。这个效果也会借助javascript实现,直接把编辑表单渲染在图片描述的下方,但是通过css属性display设置为none将表单先隐藏起来,在用户单击时通过javascript显示表单。(p347)用户资料弹窗

我们希望当鼠标悬停在某个用户的头像上时,会显示一个小弹窗来显示用户的详细信息。大致流程:鼠标悬停触发javascript函数,发送AJAX请求到某个URL,URL对应的视图函数返回数据,javascript获取到返回的数据后更新页面的内容。

具体实现较为复杂,详见(p353)。


动态显示提示消息

此外,简单的程序在出错时,可以使用alert()调用浏览器内置的弹窗组件进行提示,但不够美观。我们希望自定义一个这样的弹窗:在页面的上层动态显示,并在一定时间内自动隐藏。一般称为Toast。(p357)

Flask狼书笔记 | 09_图片社交网站 - 大型项目的架构与需求(2):https://developer.aliyun.com/article/1407227?spm=a2c6h.13148508.setting.25.79f64f0ecKMDuK

相关文章
|
2月前
|
监控 负载均衡 Dubbo
|
1月前
|
消息中间件 存储 缓存
Kafka【基础知识 01】消息队列介绍+Kafka架构及核心概念(图片来源于网络)
【2月更文挑战第20天】Kafka【基础知识 01】消息队列介绍+Kafka架构及核心概念(图片来源于网络)
91 2
|
4月前
|
前端开发 JavaScript 数据库
Flask狼书笔记 | 09_图片社交网站 - 大型项目的架构与需求(2)
9.8 收藏图片 前面已经学习过如何使用关联表来表示多对多关系,缺点是只能表示关系,不能存储数据(如我还想记录下收藏图片的时间戳)。这种情况下,我们可以使用关联模型来表示多对多关系。 在关联模型中,我们将Photo模型与User模型的多对多关系,分离成了User模型和Collect模型的一对多关系,和Photo模型与Collect模型的一对多关系。
66 0
|
2月前
|
缓存 监控 安全
如何设计大型项目技术运营服务架构
【2月更文挑战第3天】如何设计大型项目技术运营服务架构
341 1
|
2月前
|
存储 传感器 网络协议
《物联网技术》课程笔记——第二章 物联网技术架构
《物联网技术》课程笔记——第二章 物联网技术架构
|
3月前
|
达摩院 Java Apache
惊动“达摩院”的分布式架构笔记:火于互联网,据说来自于清华
一个星期前,一本Java架构笔记突然在互联网上爆火。因为内容的深度和广度,甚至连阿里最牛的研发中心都被惊动了,而且作者一周后直接被阿里挖走后定级P8,据说作者来自于清华。
|
3月前
|
安全 数据挖掘 定位技术
笔记 - 《业务架构解构与实践》
《业务架构解构与实践》的笔记
|
3月前
|
运维 Cloud Native 安全
笔记 - 《阿里云云原生架构实践》
《阿里云云原生架构实践》的笔记
|
3月前
|
NoSQL Java 程序员
阿里开发人员献礼“Java架构成长笔记”,深入内核,拒绝蒙圈
提起阿里,行外人联想到的关键词无非是“交易”、“淘宝”、“支付宝”,但对于程序员来说,阿里庞大的技术体系才是最吸引人的。实际上阿里作为国内一线互联网公司的头把交椅,内部的技术体系和发展都是备受关注的,对于程序员来说,能够进到阿里工作,就是对自己的技术水平进行一个提升和学习。
阿里开发人员献礼“Java架构成长笔记”,深入内核,拒绝蒙圈
|
3月前
|
消息中间件 架构师 Java
Java架构速成笔记:七大专题,1425页考点,挑战P8岗
我们都知道,在程序员的职业生涯中,有多个发展方向,不过就数据表明,近年来选择架构师方向的开发人员也越来越多。