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 %}