Инструменты пользователя

Инструменты сайта


учетная_запись_и_фотография_профиля

Учетная запись и фотография профиля

Настройка шаблона

Для начала, обновим шаблон пользователя account.html добавив меду тегами block content следующий снипет

<div class="content-section">
  <div class="media">
    <img class="rounded-circle account-img" src="userimage.jpg">
    <div class="media-body">
      <h2 class="account-heading">Username</h2>
      <p class="text-secondary">username@email.com</p>
    </div>
  </div>
  <!-- FORM HERE -->
</div>

И приведем account.html к такому виду:

{% extends "layout.html" %}
{% block content %}
    <div class="content-section">
      <div class="media">
        <img class="rounded-circle account-img" src="{{ image_file }}">
        <div class="media-body">
          <h2 class="account-heading">{{ current_user.username }}</h2>
          <p class="text-secondary">{{ current_user.email }}</p>
        </div>
      </div>
  <!-- FORM HERE -->
</div>
{% endblock content %}

Далее. В директории static создам каталог profile_pics где будут размещаться пользовательские изображения. Отредактируем функцию account() в route.py указав месторасположение пользовательского изображения:

@app.route("/account")
@login_required
def account():
    image-file = url_for('static', filename='profile_pics/' + current_user.image_file)
    return render_template('account.html', title='Account', image_file=image_file)

Редактирование аккаунта пользователем

forms.py

В файле forms.py создадим новую функцию – UpdateAccountForm, которая позволит пользователям обновлять данные аккаунта. В том числе – загружать свое изображение.

class UpdateAccountForm(FlaskForm):
    username = StringField('Username',
                           validators=[DataRequired(), Length(min=2, max=15)])
    email = StringField('Email',
                           validators=[DataRequired(), Email()])
    submit = SubmitField('Update')
 
    def validate_username(self, username):
        if username.data != current_user.username:
            user = User.query.filter_by(username=username.data).first()
            if user:
                raise ValidationError('That username is taken')
 
    def validate_email(self, email):
        if email.data != current_user.email:
            user = User.query.filter_by(email=email.data).first()
            if user:
                raise ValidationError('That email is taken')

И импортируем следующий модуль

from flask_login import  current_user

route.py

В route.py импортируем модуль UpdateAccountForm

from microservice.forms import RegistrationForm, LoginForm, UpdateAccountForm

и редактируем функцию – account()

@app.route("/account")
@login_required
def account():
    form = UpdateAccountForm()
    image_file = url_for('static', filename='profile_pics/' + current_user.image_file)
    return render_template('account.html', title='Account', image_file=image_file, form=form)

шаблон account.html

Теперь основательно отредактируем шаблон account.html. Данные можно скопировать из шаблона register.html и вставить в блок – <!-- FORM HERE --> и приведем код к следующему виду

{% extends "layout.html" %}
{% block content %}
    <div class="content-section">
      <div class="media">
        <img class="rounded-circle account-img" src="{{ image_file }}">
        <div class="media-body">
          <h2 class="account-heading">{{ current_user.username }}</h2>
          <p class="text-secondary">{{ current_user.email }}</p>
        </div>
      </div>
        <form method="POST" action="">
            {{ form.hidden_tag() }}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Account Info</legend>
                <div class="form-group">
                    {{ form.username.label(class="form-control-label") }}
                    {% if form.username.errors %}
                        {{ form.username(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.username.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.username(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.email.label(class="form-control-label") }}
                    {% if form.email.errors %}
                        {{ form.email(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.email.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.email(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
 
            </fieldset>
            <div class="form-group">
                {{ form.submit(class="btn btn-outline-info") }}
            </div>
        </form>
    </div>
{% endblock content %}

Добавление функционала

routes.py

Снова редактируем функцию account()</htm>

@app.route("/account", methods=['GET', 'POST'])
@login_required
def account():
    form = UpdateAccountForm()
    if form.validate_on_submit():
        current_user.username = form.username.data
        current_user.email = form.email.data
        db.session.commit()
        flash('your account has been updated!', 'success')
        return redirect(url_for('account'))
    elif request.method == 'GET':
        form.username.data = current_user.username
        form.email.data = current_user.email
    image_file = url_for('static', filename='profile_pics/' + current_user.image_file)
    return render_template('account.html', title='Account', image_file=image_file, form=form)

Изменение пользовательского изображения

Импортируем модули в routes.py

import os
import secrets

Добавляем логику, в фале routes.py создадим функцию save_picture()

def save_picture(form_picture):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_picture.filename)
    picture_fn = random_hex + f_ext
    picture_path = os.path.join(app.root_path, 'static/profile_pics', picture_fn)
    form_picture.save(picture_path)
 
    return picture_fn

А также отредактируем функцию UpdateAccountForm()

@app.route("/account", methods=['GET', 'POST'])
@login_required
def account():
    form = UpdateAccountForm()
    if form.validate_on_submit():
        if form.picture.data:
            picture_file = save_picture(form.picture.data)
            current_user.image_file = picture_file
        current_user.username = form.username.data
        current_user.email = form.email.data
        db.session.commit()
        flash('your account has been updated!', 'success')
        return redirect(url_for('account'))
    elif request.method == 'GET':
        form.username.data = current_user.username
        form.email.data = current_user.email
    image_file = url_for('static', filename='profile_pics/' + current_user.image_file)
    return render_template('account.html', title='Account', image_file=image_file, form=form)

Сжатие изображений

Устанавливаем модуль Pillow

conda install Pillow

И прописываем его в routes.py

from PIL import Image

И добавляем логику сжатия в функцию save_picture()

def save_picture(form_picture):
    random_hex = secrets.token_hex(8)
    _, f_ext = os.path.splitext(form_picture.filename)
    picture_fn = random_hex + f_ext
    picture_path = os.path.join(app.root_path, 'static/profile_pics', picture_fn)
 
    output_size = (125, 125)
    i = Image.open(form_picture)
    i.thumbnail(output_size)
    i.save(picture_path)
 
    return picture_fn

see also

учетная_запись_и_фотография_профиля.txt · Последнее изменение: 2021/03/12 15:21 — admin