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_login import current_user
from flask_wtf import FlaskForm from wtforms import BooleanField, SelectField
from wtforms import (BooleanField, SelectField, StringField, SubmitField, from ..models import Role
ValidationError) from ..settings.forms import EditGeneralSettingsForm
from wtforms.validators import DataRequired, Email, Length, Regexp
from ..models import Role, User
class EditUserForm(FlaskForm): class EditGeneralSettingsAdminForm(EditGeneralSettingsForm):
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')]
)
confirmed = BooleanField('Confirmed') confirmed = BooleanField('Confirmed')
role = SelectField( role = SelectField('Role', coerce=int)
'Role',
choices = [(role.id, role.name)
for role in Role.query.order_by(Role.name).all()],
coerce=int
)
submit = SubmitField('Update Profile')
def __init__(self, user, *args, **kwargs): def __init__(self, user=current_user, *args, **kwargs):
super().__init__(*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.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 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 . import admin
from .forms import EditUserForm from .forms import EditGeneralSettingsAdminForm
from .. import db from .. import db
from ..decorators import admin_required from ..decorators import admin_required
from ..models import Role, User from ..models import Role, User
@ -39,22 +39,29 @@ def delete_user(user_id):
return redirect(url_for('admin.index')) 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 @login_required
@admin_required @admin_required
def edit_user(user_id): def edit_general_settings(user_id):
user = User.query.get_or_404(user_id) user = User.query.get_or_404(user_id)
edit_user_form = EditUserForm(user=user) form = EditGeneralSettingsAdminForm(user=user)
if edit_user_form.validate_on_submit(): if form.validate_on_submit():
user.email = edit_user_form.email.data user.setting_dark_mode = form.dark_mode.data
user.username = edit_user_form.username.data user.email = form.email.data
user.confirmed = edit_user_form.confirmed.data user.username = form.username.data
user.role = Role.query.get(edit_user_form.role.data) user.confirmed = form.confirmed.data
user.role = Role.query.get(form.role.data)
db.session.add(user) db.session.add(user)
db.session.commit() db.session.commit()
flash('The profile has been updated.') flash('The profile has been updated.')
return redirect(url_for('admin.edit_user', user_id=user.id)) return redirect(url_for('admin.edit_general_settings', user_id=user.id))
return render_template('admin/edit_user.html.j2', form.confirmed.data = user.confirmed
edit_user_form=edit_user_form, form.dark_mode.data = user.setting_dark_mode
title='Edit user', 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) user=user)

View File

@ -4,6 +4,7 @@ from flask_wtf import FlaskForm
from wtforms import (BooleanField, PasswordField, SelectField, StringField, from wtforms import (BooleanField, PasswordField, SelectField, StringField,
SubmitField, ValidationError) SubmitField, ValidationError)
from wtforms.validators import DataRequired, Email, EqualTo, Length, Regexp from wtforms.validators import DataRequired, Email, EqualTo, Length, Regexp
from ..models import User
class ChangePasswordForm(FlaskForm): class ChangePasswordForm(FlaskForm):
@ -43,9 +44,6 @@ class EditGeneralSettingsForm(FlaskForm):
def __init__(self, user=current_user, *args, **kwargs): def __init__(self, user=current_user, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.user = user 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): def validate_email(self, field):
if (field.data != self.user.email if (field.data != self.user.email
@ -78,9 +76,3 @@ class EditNotificationSettingsForm(FlaskForm):
def __init__(self, user=current_user, *args, **kwargs): def __init__(self, user=current_user, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.user = user 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') title='Change password')
@settings.route('/edit_general_settings') @settings.route('/edit_general_settings', methods=['GET', 'POST'])
@login_required @login_required
def edit_general_settings(): def edit_general_settings():
form = EditGeneralSettingsForm() form = EditGeneralSettingsForm()
@ -40,12 +40,15 @@ def edit_general_settings():
current_user.username = form.username.data current_user.username = form.username.data
db.session.commit() db.session.commit()
flash('Your changes have been saved.') 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', return render_template('settings/edit_general_settings.html.j2',
form=form, form=form,
title='General settings') title='General settings')
@settings.route('/edit_notification_settings') @settings.route('/edit_notification_settings', methods=['GET', 'POST'])
@login_required @login_required
def edit_notification_settings(): def edit_notification_settings():
form = EditNotificationSettingsForm() form = EditNotificationSettingsForm()
@ -56,6 +59,10 @@ def edit_notification_settings():
form.job_status_site_notifications.data form.job_status_site_notifications.data
db.session.commit() db.session.commit()
flash('Your changes have been saved.') 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', return render_template('settings/edit_notification_settings.html.j2',
form=form, form=form,
title='Notification settings') 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> </ul>
</div> </div>
<div class="card-action right-align"> <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> <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>
</div> </div>