您现在的位置是:首页 >技术教程 >Flask 设置头像及创建帖子模型类网站首页技术教程
Flask 设置头像及创建帖子模型类
简介Flask 设置头像及创建帖子模型类
我们经常在一些网站上看到,在用户没有自定义头像的情况下,会给每个用户都生成一个头像,这让网站显得更美观,那这个是怎么实现的呢?在Flask中有一个插件,叫做Flask-avatars,专门提供头像解决方案。里面集成了各种头像解决方案。下面就来讲解一下。
一、安装
pip install flask-avatars
二、初始化
扩展需要以通常的方式初始化,然后才能使用:
from flask_avatars import Avatars
app = Flask(__name__)
avatars = Avatars(app)
三、配置
下面列出了可用的配置选项:
四、头像
Flask-Avatarsavatars在模板上下文中提供了一个对象,您可以使用它来获取头像 URL。
1. Gravatar:
关于什么是Gravatar,这里引用了维基百科的一段介绍供读者参考:
在Gravatar上,用户可以用他们的电子邮件注册一个帐号,并且上传一个与之绑定的头像。许多流行的博客程序都支持Gravatar,包括WordpressTypecho等著名博客程序,当用户发布一个评论并填写了他的电子邮件地址时,博客程序会自动查找在Gravatar上是否有与之绑定的头像。如果有,则这个头像将会与评论一起显示出来。WordPress v2.5 开始原生地提供对Gravatar的支持。此外还有许多程序通过插件来支持Gravatar,例如论坛程序Discuz!。
一个Gravatar头像可以使用高达512像素的图片,并且默认地以80*80的尺寸显示出来。如果上传的头像不是这个尺寸,Gravatar会对头像进行缩放。用户可以按照MPAA分级制度确定自己的头像级别,这样网站管理员可以在他们的站点上显示合适的头像。
为了防止用户的电子邮件地址遭到泄漏而收到大量垃圾邮件,Gravatar在传递用户的邮箱地址时采用的是通过MD5散列运算的邮件地址。
更多关于Gravatar的介绍请参考:https://zh.wikipedia.org/wiki/Gravatar
您可以使用avatars.gravatar()获取Gravatar提供的头像 URL ,传递电子邮件哈希:
<img src="{{ avatars.gravatar(email_hash) }}"/>
您可以像这样获得电子邮件哈希:
import hashlib
avatar_hash = hashlib.md5(my_email.lower().encode('utf-8')).hexdigest()
2. 标识生成
Flask-Avatars 提供了一个Identicon生成identicon avatar的类,大部分代码基于randomavatar。首先,您需要设置配置变量AVATARS_SAVE_PATH来告诉 Flask-Avatars 保存生成的头像的路径。一般来说,我们会在创建用户记录的时候生成头像,所以生成头像最好的地方是在用户数据库模型类中:
首先在exts中新建avatars对象
from flask_avatars import Avatars
avatars = Avatars()
在app.py中
注册的时候就保存到数据库
在配置文件config中保存头像的路径
# 头像配置
AVATARS_SAVE_PATH = os.path.join(BASE_DIR, "media", "avatars")
在项目的根路径下新建media/avatars 用以存放所有头像
然后在apps中新建media包/views文件
注册保存头像
用户上传自定义图像
@bp.post("/avatar/upload")
@login_required
def upload_avatar():
form = UploadImageForm(request.files)
if form.validate():
image = form.image.data
# 不要使用用户上传上来的文件名,否则容易被黑客攻击
filename = image.filename
# xxx.png,xx.jpeg 分割拿到后缀名
_, ext = os.path.splitext(filename)
filename = md5((g.user.email + str(time.time())).encode("utf-8")).hexdigest() + ext
image_path = os.path.join(current_app.config['AVATARS_SAVE_PATH'], filename)
image.save(image_path)
# 看个人需求,是否图片上传完成后要立马修改用户的头像字段
g.user.avatar = filename
db.session.commit()
return restful.ok(data={"avatar": filename})
else:
message = form.messages[0]
return restful.params_error(message=message)
class UploadImageForm(BaseForm):
image = FileField(validators=[FileAllowed(['jpg', 'jpeg', 'png'], message="图片格式不符合要求!"), FileSize(max_size=1024*1024*5, message="图片最大不能超过5M!")])
个性签名
@bp.post("/profile/edit")
@login_required
def edit_profile():
form = EditProfileForm(request.form)
if form.validate():
signature = form.signature.data
g.user.signature = signature
db.session.commit()
return restful.ok()
else:
return restful.params_error(message=form.messages[0])
class EditProfileForm(BaseForm):
signature = StringField(validators=[Length(min=1, max=50, message="个性签名长度在1-50字之间!")])
命令行自定义命令的初始化
增加板块的模型类
from exts import db
from datetime import datetime
# from sqlalchemy_serializer import SerializerMixin
# 帖子板块模型类
class BoardModel(db.Model):
serialize_only = ("id", "name", "priority", "create_time")
__tablename__ = "board"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20), unique=True)
# 板块权重
priority = db.Column(db.Integer, default=1)
create_time = db.Column(db.DateTime, default=datetime.now)
# 帖子
class PostModel(db.Model):
serialize_only = ("id", "title", "content", "create_time", "board", "author")
__tablename__ = "post"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text, nullable=False)
create_time = db.Column(db.DateTime, default=datetime.now)
# 帖子板块外键
board_id = db.Column(db.Integer, db.ForeignKey("board.id"))
# 作者
author_id = db.Column(db.String(100), db.ForeignKey("user.id"))
#通过帖子属性可以直接访问所属板块 反向引用 有板块对象可以访问板块下所有模型
board = db.relationship("BoardModel", backref=db.backref("posts"))
author = db.relationship("UserModel", backref=db.backref("posts"))
# 轮播图
class BannerModel(db.Model):
__tablename__ = 'banner'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# 图片名字
name = db.Column(db.String(255), nullable=False)
# 图片链接
image_url = db.Column(db.String(255), nullable=False)
# 跳转链接
link_url = db.Column(db.String(255), nullable=False)
# 优先级
priority = db.Column(db.Integer, default=0)
create_time = db.Column(db.DateTime, default=datetime.now)
# 评论
class CommentModel(db.Model):
__tablename__ = 'comment'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
content = db.Column(db.Text, nullable=False)
create_time = db.Column(db.DateTime, default=datetime.now)
# 所属帖子的id
post_id = db.Column(db.Integer, db.ForeignKey("post.id"))
# 作者的id
author_id = db.Column(db.String(100), db.ForeignKey("user.id"), nullable=False)
# 评论排序 帖子删除评论也删除
post = db.relationship("PostModel", backref=db.backref('comments', order_by="CommentModel.create_time.desc()", cascade="delete, delete-orphan"))
author = db.relationship("UserModel", backref='comments')
获取板块数据渲染模板
boards = BoardModel.query.order_by(BoardModel.priority.desc()).all()
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。