From c4274e3b743f9679d421ff48afecad81d0ef223d Mon Sep 17 00:00:00 2001 From: tmeissner Date: Mon, 12 Nov 2018 23:30:00 +0100 Subject: [PATCH] Chapter 10: Profiles editor (10b) --- app/main/forms.py | 46 +++++++++++++++++++++++++-- app/main/views.py | 56 +++++++++++++++++++++++++++++++-- app/templates/edit_profile.html | 13 ++++++++ app/templates/user.html | 8 +++++ 4 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 app/templates/edit_profile.html diff --git a/app/main/forms.py b/app/main/forms.py index 2ca9277..9c7b3dc 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1,8 +1,50 @@ from flask_wtf import FlaskForm -from wtforms import StringField, SubmitField -from wtforms.validators import DataRequired +from wtforms import StringField, SubmitField, TextAreaField, BooleanField, \ + SelectField +from wtforms.validators import DataRequired, Length, Email, Regexp +from wtforms import ValidationError +from ..models import Role, User class NameForm(FlaskForm): name = StringField('What is your name?', validators=[DataRequired()]) submit = SubmitField('Submit') + + +class EditProfileForm(FlaskForm): + name = StringField('Real name', validators=[Length(0, 64)]) + location = StringField('Location', validators=[Length(0, 64)]) + about_me = TextAreaField('About me') + submit = SubmitField('Submit') + + +class EditProfileAdminForm(FlaskForm): + email = StringField('Email', validators=[DataRequired(), Length(1, 64), + Email()]) + username = StringField('Username', validators=[ + DataRequired(), Length(1, 64), + Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0, + 'Usernames must have only letters, numbers, dots or ' + 'underscores')]) + confirmed = BooleanField('Confirmed') + role = SelectField('Role', coerce=int) + name = StringField('Real name', validators=[Length(0, 64)]) + location = StringField('Location', validators=[Length(0, 64)]) + about_me = TextAreaField('About me') + submit = SubmitField('Submit') + + def __init__(self, user, *args, **kwargs): + super(EditProfileAdminForm, self).__init__(*args, **kwargs) + self.role.choices = [(role.id, role.name) + for role in Role.query.order_by(Role.name).all()] + self.user = user + + def validate_email(self, field): + if field.data != self.user.email and \ + User.query.filter_by(email=field.data).first(): + raise ValidationError('Email already registered') + + def validate_username(self, field): + if field.data != self.user.username and \ + User.query.filter_by(username=field.data).first(): + raise ValidationError('Username already in use.') diff --git a/app/main/views.py b/app/main/views.py index edd98c4..f96fa59 100644 --- a/app/main/views.py +++ b/app/main/views.py @@ -1,9 +1,13 @@ -from flask import render_template +from flask import render_template, redirect, url_for, flash +from flask_login import login_required, current_user from . import main -from ..models import User +from .forms import EditProfileForm, EditProfileAdminForm +from .. import db +from ..models import User, Role +from ..decorators import admin_required -@main.route('/', methods=['GET', 'POST']) +@main.route('/') def index(): return render_template('index.html') @@ -12,3 +16,49 @@ def index(): def user(username): user = User.query.filter_by(username=username).first_or_404() return render_template('user.html', user=user) + + +@main.route('/edit-profile', methods=['GET', 'POST']) +@login_required +def edit_profile(): + form = EditProfileForm() + if form.validate_on_submit(): + current_user.name = form.name.data + current_user.location = form.location.data + current_user.about_me = form.about_me.data + db.session.add(current_user._get_current_object()) + db.session.commit() + flash('Your profile has been updated.') + return redirect(url_for('.user', username=current_user.username)) + form.name.data = current_user.name + form.location.data = current_user.location + form.about_me.data = current_user.about_me + return render_template('edit_profile.html', form=form) + + +@main.route('/edit-profile/', methods=['GET', 'POST']) +@login_required +@admin_required +def edit_profile_admin(id): + user = User.query.get_or_404(id) + form = EditProfileAdminForm(user=user) + if form.validate_on_submit(): + user.email = form.email.data + user.username = form.username.data + user.comfirmed = form.confirmed.data + user.role = Role.query.get(form.role.data) + user.name = form.name.data + user.location = form.location.data + user.about_me = form.about_me.data + db.session.add(user) + db.session.commit() + flash('The profile has been updated.') + return redirect(url_for('.user', username=user.username)) + form.email.data = user.email + form.username.data = user.username + form.confirmed.data = user.confirmed + form.role.data = user.role_id + form.name.data = user.name + form.location.data = user.location + form.about_me.data = user.about_me + return render_template('edit_profile.html', form=form, user=user) diff --git a/app/templates/edit_profile.html b/app/templates/edit_profile.html new file mode 100644 index 0000000..44bd7fa --- /dev/null +++ b/app/templates/edit_profile.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} +{% import "bootstrap/wtf.html" as wtf %} + +{% block title %}Flasky - Edit Profile{% endblock %} + +{% block page_content %} + +
+ {{ wtf.quick_form(form) }} +
+{% endblock %} diff --git a/app/templates/user.html b/app/templates/user.html index 3b004d0..3122584 100644 --- a/app/templates/user.html +++ b/app/templates/user.html @@ -25,5 +25,13 @@ Member since {{ moment(user.member_since).format('L') }}. Last seen {{ moment(user.last_seen).fromNow() }}.

+

+ {% if user == current_user %} + Edit Profile + {% endif %} + {% if current_user.is_administrator %} + Edit Profile [Admin] + {% endif %} +

{% endblock %}