We often see on some websites that if the user does not have a custom avatar, an avatar will be generated for each user, which makes the website look more beautiful. How is this achieved? There is a plugin in Flask called Flask-avatars that provides avatar solutions. It integrates various avatar solutions. Let’s explain it below.
1. Install
pip install flask-avatars
2. Initialization
Extensions need to be initialized in the usual way before they can be used:
from flask_avatars import Avatars app = Flask(__name__) avatars = Avatars(app)
3. Configuration
The available configuration options are listed below:
4. Avatar
Flask-Avatarsavatars provides an object in the template context that you can use to get the avatar URL.
1. Gravatar:
Regarding what is Gravatar, here is an introduction from Wikipedia for readers’ reference:
On Gravatar, users can sign up for an account with their email and upload an avatar tied to it. Many popular blog programs support Gravatar, including famous blog programs such as WordPressTypecho. When a user posts a comment and fills in his email address, the blog program will automatically check whether there is an avatar bound to it on Gravatar. If available, the avatar will be displayed with the comment. WordPress v2.5 began to provide native support for Gravatar. In addition, there are many programs that support Gravatar through plug-ins, such as the forum program Discuz!. A Gravatar avatar can use images up to 512 pixels, and by default it will be displayed in 80*80 size. If the uploaded avatar is not of this size, Gravatar will scale the avatar. Users can determine their avatar level according to the MPAA grading system, so that webmasters can display appropriate avatars on their sites. In order to prevent the user's email address from being leaked and receive a large amount of spam, Gravatar uses the email address through MD5 hash operation when delivering the user's email address. For more information on Gravatar, please refer to: https://zh.wikipedia.org/wiki/Gravatar
You can use avatars.gravatar() to get the avatar URL provided by Gravatar, passing the email hash:
<img src="{<!-- -->{ avatars.gravatar(email_hash) }}"/>
You can get email hash like this:
import hashlib avatar_hash = hashlib.md5(my_email.lower().encode('utf-8')).hexdigest()
2. Logo generation
Flask-Avatars provides an Identicon class that generates identicon avatars, and most of the code is based on random avatars. First, you need to set the configuration variable AVATARS_SAVE_PATH to tell Flask-Avatars the path to save the generated avatars. Generally speaking, we will generate an avatar when creating a user record, so the best place to generate an avatar is in the user database model class:
First create a new avatars object in exts
from flask_avatars import Avatars avatars = Avatars()
in app.py
When registering, it is saved to the database
The path to save the avatar in the configuration file config
# Avatar configuration AVATARS_SAVE_PATH = os.path.join(BASE_DIR, "media", "avatars")
Create a new media/avatars under the root path of the project to store all avatars
Then create a new media package/views file in apps
Register to save avatar
User uploads a custom image
@bp.post("/avatar/upload") @login_required def upload_avatar(): form = UploadImageForm(request.files) if form. validate(): image = form.image.data # Do not use the file name uploaded by the user, otherwise it is easy to be hacked filename = image.filename # xxx.png, xx.jpeg split to get the suffix name _, 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) # Depending on personal needs, whether to modify the user's avatar field immediately after the image upload is completed 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="The image format does not meet the requirements!"), FileSize(max_size=1024*1024*5, message="The image is the largest Cannot exceed 5M!")])
Signature
@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="The length of the personalized signature is between 1-50 words!")])
Initialization of command line custom commands
Increase the model class of the plate
from exts import db from datetime import datetime # from sqlalchemy_serializer import SerializerMixin # Post section model class 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) # Block weight priority = db.Column(db.Integer, default=1) create_time = db.Column(db.DateTime, default=datetime.now) # posts 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) # Post section foreign key board_id = db.Column(db.Integer, db.ForeignKey("board.id")) # author author_id = db.Column(db.String(100), db.ForeignKey("user.id")) #Through the attribute of the post, you can directly access the section you belong to. Back reference, if you have a section object, you can access all the models under the section board = db. relationship("BoardModel", backref=db. backref("posts")) author = db.relationship("UserModel", backref=db.backref("posts")) # carousel class BannerModel(db.Model): __tablename__ = 'banner' id = db.Column(db.Integer, primary_key=True, autoincrement=True) # image name name = db.Column(db.String(255), nullable=False) # image link image_url = db.Column(db.String(255), nullable=False) # jump link link_url = db.Column(db.String(255), nullable=False) # priority priority = db.Column(db.Integer, default=0) create_time = db.Column(db.DateTime, default=datetime.now) # Comment 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) # The id of the post to which it belongs post_id = db.Column(db.Integer, db.ForeignKey("post.id")) # author's id author_id = db.Column(db.String(100), db.ForeignKey("user.id"), nullable=False) # Comment sorting post delete comment also delete post = db.relationship("PostModel", backref=db.backref('comments', order_by="CommentModel.create_time.desc()", cascade="delete, delete-orphan")) author = db. relationship("UserModel", backref='comments')
Get the template data rendering template
boards = BoardModel.query.order_by(BoardModel.priority.desc()).all()