Skip to content
Snippets Groups Projects

Place editing

Merged Jiří Setnička requested to merge jirka/schools into master
6 files
+ 151
3
Compare changes
  • Side-by-side
  • Inline

Files

  • f56a54d5
    Editace míst · f56a54d5
    Jiří Setnička authored
    Používá flask_bootstrap na vykreslení formu.
    
    Po editaci zkontroluje změny v objektu a pokud nějaké nastaly, tak
    uloží + zaloguje do databáze.
    
    Přesun místa pod jiné místo je zatím work-in-progress.
+ 188
3
from flask import render_template, g, redirect, url_for
from flask import render_template, g, redirect, url_for, flash, request
from flask_wtf import FlaskForm
from sqlalchemy.orm import joinedload
import werkzeug.exceptions
import wtforms
import mo
import mo.db as db
import mo.rights
from mo.web import app
import wtforms.validators as validators
@app.route('/org/')
@@ -30,7 +32,190 @@ def org_place(id: int):
rr = mo.rights.Rights(g.user)
rr.get_for(place)
return render_template('org_place.html', place=place, school=school, rights=rr.current_rights)
return render_template(
'org_place.html', place=place, school=school, rights=rr.current_rights,
can_edit=rr.can_edit_place(place)
)
class PlaceEditForm(FlaskForm):
name = wtforms.StringField(
'Název',
validators=[validators.DataRequired()]
)
code = wtforms.StringField(
'Kód', filters=[lambda x: x or None], # may be NULL in db
description="Při nevyplnění se použije ID místa"
)
type = wtforms.SelectField(
'Typ', choices=db.PlaceType.choices(), coerce=db.PlaceType.coerce
)
nuts = wtforms.StringField(
'NUTS', filters=[lambda x: x or None], # may be NULL in db
description="Pro okresy a výše"
)
note = wtforms.StringField('Poznámka')
submit = wtforms.SubmitField('Uložit')
class PlaceSchoolEditForm(PlaceEditForm):
red_izo = wtforms.StringField('RED_IZO')
official_name = wtforms.StringField('Oficiální název')
address = wtforms.StringField('Adresa')
is_zs = wtforms.BooleanField('')
is_ss = wtforms.BooleanField('')
submit = wtforms.SubmitField('Uložit')
@app.route('/org/place/<int:id>/edit', methods=('GET', 'POST'))
def org_place_edit(id: int):
sess = db.get_session()
place = sess.query(db.Place).get(id)
if not place:
raise werkzeug.exceptions.NotFound()
rr = mo.rights.Rights(g.user)
rr.get_for(place)
if not rr.can_edit_place(place):
raise werkzeug.exceptions.Forbidden()
if place.type == db.PlaceType.school:
school = sess.query(db.School).get(place.place_id)
# Pass school data as additional dict (data is used after obj)
form = PlaceSchoolEditForm(obj=place, data=db.row2dict(school))
else:
form = PlaceEditForm(obj=place)
school = None
if form.validate_on_submit():
form.populate_obj(place)
if school:
form.populate_obj(school)
msg = 'Změny místa uloženy'
redirectURL = url_for('org_place', id=id)
if sess.is_modified(place) or school and sess.is_modified(school):
placeChanges = db.get_object_changes(place)
schoolChanges = {}
if school:
if request.form.get('type') != 'school':
# School record removed
mo.util.log(
type=db.LogType.place,
what=g.user.user_id,
details={'action': 'school-delete', 'school': db.row2dict(school)},
)
app.logger.info(f"Deleting school record for place {place.place_id}")
db.get_session().delete(school)
msg = 'Změny místa uloženy, záznam o škole smazán'
else:
schoolChanges = db.get_object_changes(school)
elif request.form.get('type') == 'school':
# School record created
newSchool = db.School()
newSchool.place_id = place.place_id
mo.util.log(
type=db.LogType.place,
what=g.user.user_id,
details={'action': 'school-add', 'place_id': place.place_id},
)
app.logger.info(f"Creating new school for place {place.place_id}")
db.get_session().add(newSchool)
# Take org directly to the school edit to fill the data
msg = 'Záznam o škole vytvořen, vyplňte prosím všechna data'
redirectURL = url_for('org_place_edit', id=id)
changes = {**placeChanges, **schoolChanges}
app.logger.info(f"Place {id} modified, changes: {changes}")
mo.util.log(
type=db.LogType.place,
what=g.user.user_id,
details={'action': 'edit', 'changes': changes},
)
db.get_session().commit()
flash(msg, 'success')
else:
flash(u'Žádné změny k uložení', 'info')
return redirect(redirectURL)
parents = reversed(db.get_place_parents(place)[1:]) # without place itself and from the top
return render_template(
'org_place_edit.html', place=place, school=school,
parents=parents, form=form
)
@app.route('/org/place/<int:id>/delete', methods=('POST',))
def org_place_delete(id: int):
sess = db.get_session()
# Tests: can delete only existing places that we can edit
place = sess.query(db.Place).get(id)
if not place:
raise werkzeug.exceptions.NotFound()
rr = mo.rights.Rights(g.user)
rr.get_for(place)
if not rr.can_edit_place(place):
raise werkzeug.exceptions.Forbidden()
# Cannot delete place with children
if place.children:
flash("Nelze smazat místo s podřízenými místy", "danger")
return redirect(url_for('org_place', id=id))
if place.type == db.PlaceType.school:
school = sess.query(db.School).get(place.place_id)
db.get_session().delete(school)
parent = place.parent
db.get_session().delete(place)
db.get_session().commit()
flash("Místo smazáno", "success")
return redirect(url_for('org_place', id=parent))
@app.route('/org/place/<int:id>/new-child', methods=('GET', 'POST'))
def org_place_new_child(id: int):
sess = db.get_session()
# Tests: can add new child only under existing places that we can edit
parentPlace = sess.query(db.Place).get(id)
if not parentPlace:
raise werkzeug.exceptions.NotFound()
rr = mo.rights.Rights(g.user)
rr.get_for(parentPlace)
if not rr.can_edit_place(parentPlace):
raise werkzeug.exceptions.Forbidden()
form = PlaceEditForm()
if form.validate_on_submit():
new_place = db.Place()
form.populate_obj(new_place)
new_place.parent = parentPlace.place_id
new_place.level = parentPlace.level + 1
db.get_session().add(new_place)
app.logger.info(f"New place created: {db.row2dict(new_place)}")
mo.util.log(
type=db.LogType.place,
what=g.user.user_id,
details={'action': 'new', 'place': db.row2dict(new_place)},
)
db.get_session().commit()
flash(u'Nové místo uloženo', 'success')
return redirect(url_for('org_place', id=new_place.place_id))
parents = reversed(db.get_place_parents(parentPlace))
return render_template('org_place_new.html', parents=parents, form=form)
@app.route('/org/place/')
Loading