您现在的位置是:首页 >技术教程 >Flask 设置头像及创建帖子模型类网站首页技术教程

Flask 设置头像及创建帖子模型类

季布, 2024-06-19 13:56:27
简介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()

在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。