Set default form values in view function. Use inheritance for admin forms

This commit is contained in:
Patrick Jentsch 2020-10-27 14:23:23 +01:00
parent 58e5116eb3
commit 934ec4af42
7 changed files with 112 additions and 100 deletions

View File

@ -1,44 +1,15 @@
from flask import current_app
from flask_wtf import FlaskForm
from wtforms import (BooleanField, SelectField, StringField, SubmitField,
ValidationError)
from wtforms.validators import DataRequired, Email, Length, Regexp
from ..models import Role, User
from flask_login import current_user
from wtforms import BooleanField, SelectField
from ..models import Role
from ..settings.forms import EditGeneralSettingsForm
class EditUserForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
username = StringField(
'Username',
validators=[DataRequired(),
Length(1, 64),
Regexp(current_app.config['ALLOWED_USERNAME_REGEX'],
message='Usernames must have only letters, numbers,'
' dots or underscores')]
)
class EditGeneralSettingsAdminForm(EditGeneralSettingsForm):
confirmed = BooleanField('Confirmed')
role = SelectField(
'Role',
choices = [(role.id, role.name)
for role in Role.query.order_by(Role.name).all()],
coerce=int
)
submit = SubmitField('Update Profile')
role = SelectField('Role', coerce=int)
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
def __init__(self, user=current_user, *args, **kwargs):
super().__init__(*args, user=user, **kwargs)
self.role.choices = [(role.id, role.name)
for role in Role.query.order_by(Role.name).all()]
self.user = user
self.email.data = self.email.data or user.email
self.username.data = self.username.data or user.username
self.confirmed.data = self.confirmed.data or user.confirmed
self.role.data = self.role.data or user.role_id
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.')

View File

@ -1,7 +1,7 @@
from flask import flash, redirect, render_template, url_for
from flask_login import login_required
from flask_login import current_user, login_required
from . import admin
from .forms import EditUserForm
from .forms import EditGeneralSettingsAdminForm
from .. import db
from ..decorators import admin_required
from ..models import Role, User
@ -39,22 +39,29 @@ def delete_user(user_id):
return redirect(url_for('admin.index'))
@admin.route('/users/<int:user_id>/edit', methods=['GET', 'POST'])
@admin.route('/users/<int:user_id>/edit_general_settings',
methods=['GET', 'POST'])
@login_required
@admin_required
def edit_user(user_id):
def edit_general_settings(user_id):
user = User.query.get_or_404(user_id)
edit_user_form = EditUserForm(user=user)
if edit_user_form.validate_on_submit():
user.email = edit_user_form.email.data
user.username = edit_user_form.username.data
user.confirmed = edit_user_form.confirmed.data
user.role = Role.query.get(edit_user_form.role.data)
form = EditGeneralSettingsAdminForm(user=user)
if form.validate_on_submit():
user.setting_dark_mode = form.dark_mode.data
user.email = form.email.data
user.username = form.username.data
user.confirmed = form.confirmed.data
user.role = Role.query.get(form.role.data)
db.session.add(user)
db.session.commit()
flash('The profile has been updated.')
return redirect(url_for('admin.edit_user', user_id=user.id))
return render_template('admin/edit_user.html.j2',
edit_user_form=edit_user_form,
title='Edit user',
return redirect(url_for('admin.edit_general_settings', user_id=user.id))
form.confirmed.data = user.confirmed
form.dark_mode.data = user.setting_dark_mode
form.email.data = user.email
form.role.data = user.role_id
form.username.data = user.username
return render_template('admin/edit_general_settings.html.j2',
form=form,
title='General settings',
user=user)

View File

@ -4,6 +4,7 @@ from flask_wtf import FlaskForm
from wtforms import (BooleanField, PasswordField, SelectField, StringField,
SubmitField, ValidationError)
from wtforms.validators import DataRequired, Email, EqualTo, Length, Regexp
from ..models import User
class ChangePasswordForm(FlaskForm):
@ -43,9 +44,6 @@ class EditGeneralSettingsForm(FlaskForm):
def __init__(self, user=current_user, *args, **kwargs):
super().__init__(*args, **kwargs)
self.user = user
self.email.data = self.email.data or user.email
self.dark_mode.data = self.dark_mode.data or user.setting_dark_mode
self.username.data = self.username.data or user.username
def validate_email(self, field):
if (field.data != self.user.email
@ -78,9 +76,3 @@ class EditNotificationSettingsForm(FlaskForm):
def __init__(self, user=current_user, *args, **kwargs):
super().__init__(*args, **kwargs)
self.user = user
self.job_status_mail_notifications.data = \
self.job_status_mail_notifications.data \
or user.setting_job_status_mail_notifications
self.job_status_site_notifications.data = \
self.job_status_site_notifications.data \
or user.setting_job_status_site_notifications

View File

@ -30,7 +30,7 @@ def change_password():
title='Change password')
@settings.route('/edit_general_settings')
@settings.route('/edit_general_settings', methods=['GET', 'POST'])
@login_required
def edit_general_settings():
form = EditGeneralSettingsForm()
@ -40,12 +40,15 @@ def edit_general_settings():
current_user.username = form.username.data
db.session.commit()
flash('Your changes have been saved.')
form.dark_mode.data = current_user.setting_dark_mode
form.email.data = current_user.email
form.username.data = current_user.username
return render_template('settings/edit_general_settings.html.j2',
form=form,
title='General settings')
@settings.route('/edit_notification_settings')
@settings.route('/edit_notification_settings', methods=['GET', 'POST'])
@login_required
def edit_notification_settings():
form = EditNotificationSettingsForm()
@ -56,6 +59,10 @@ def edit_notification_settings():
form.job_status_site_notifications.data
db.session.commit()
flash('Your changes have been saved.')
form.job_status_mail_notifications.data = \
current_user.setting_job_status_mail_notifications
form.job_status_site_notifications.data = \
current_user.setting_job_status_site_notifications
return render_template('settings/edit_notification_settings.html.j2',
form=form,
title='Notification settings')

View File

@ -0,0 +1,70 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1 id="title">Edit user</h1>
</div>
<div class="col s12 m4">
<h2>{{ user.username }}</h2>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,</p>
<a class="waves-effect waves-light btn" href="{{ url_for('.user', user_id=user.id) }}"><i class="material-icons left">arrow_back</i>Back to user administration</a>
</div>
<div class="col s12 m8">
<div class="card">
<form method="POST">
<div class="card-content">
{{ form.hidden_tag() }}
{{ wtf.render_field(form.username, data_length='64', material_icon='account_circle') }}
{{ wtf.render_field(form.email, class_='validate', material_icon='email', type='email') }}
{{ wtf.render_field(form.role, material_icon='swap_vert') }}
<div class="row">
<div class="col s12"><p>&nbsp;</p></div>
<div class="col s1">
<p><i class="material-icons">brightness_3</i></p>
</div>
<div class="col s8">
<p>{{ form.dark_mode.label.text }}</p>
<p class="light">Enable dark mode to ease your eyes.</p>
</div>
<div class="col s3 right-align">
<div class="switch">
<label>
{{ form.dark_mode() }}
<span class="lever"></span>
</label>
</div>
</div>
<div class="col s12"><p>&nbsp;</p></div>
<div class="col s12 divider"></div>
<div class="col s12"><p>&nbsp;</p></div>
<div class="col s1">
<p><i class="material-icons">check</i></p>
</div>
<div class="col s8">
<p>{{ form.confirmed.label.text }}</p>
<p class="light">Change confirmation status manually.</p>
</div>
<div class="col s3 right-align">
<div class="switch">
<label>
{{ form.confirmed() }}
<span class="lever"></span>
</label>
</div>
</div>
</div>
</div>
<div class="card-action right-align">
{{ wtf.render_field(form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,35 +0,0 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1 id="title">Edit user</h1>
</div>
<div class="col s12 m4">
<h2>{{ user.username }}</h2>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,</p>
<a class="waves-effect waves-light btn" href="{{ url_for('.user', user_id=user.id) }}"><i class="material-icons left">arrow_back</i>Back to user administration</a>
</div>
<div class="col s12 m8">
<div class="card">
<form method="POST">
<div class="card-content">
{{ edit_user_form.hidden_tag() }}
{{ wtf.render_field(edit_user_form.username, data_length='64', material_icon='account_circle') }}
{{ wtf.render_field(edit_user_form.email, class_='validate', material_icon='email', type='email') }}
{{ wtf.render_field(edit_user_form.role, material_icon='swap_vert') }}
{{ wtf.render_field(edit_user_form.confirmed, material_icon='check') }}
</div>
<div class="card-action right-align">
{{ wtf.render_field(edit_user_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -30,7 +30,7 @@
</ul>
</div>
<div class="card-action right-align">
<a href="{{ url_for('.edit_user', user_id=user.id) }}" class="waves-effect waves-light btn"><i class="material-icons left">edit</i>Edit</a>
<a href="{{ url_for('.edit_general_settings', user_id=user.id) }}" class="waves-effect waves-light btn"><i class="material-icons left">edit</i>Edit</a>
<a data-target="delete-user-modal" class="waves-effect waves-light btn red modal-trigger"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>