diff options
author | 2018-05-14 20:42:41 +0100 | |
---|---|---|
committer | 2018-05-14 20:42:41 +0100 | |
commit | b7fe5de12be5c9f02adeedba45befee751ea68be (patch) | |
tree | 740be4b7dff4a8e70616e1663375ef1940604d53 /pysite/views/staff/tables/edit.py | |
parent | Switch from using abort to using werkzeug exception (diff) |
Migration runner and migrations (#69)
* Migration runner and migrations
* Remove demo wiki data
* [Staff] Table management pages
* Fix weird travis build omission
* Address review and comments by @Volcyy
* [Tables] Fix pagination
* Move table definitions to new file with nameduple
* Linting
* Address lemon's review comments
* Address @Volcyy's review
* Address lemon's review
* Update search placeholder
* Search by key now available
Diffstat (limited to 'pysite/views/staff/tables/edit.py')
-rw-r--r-- | pysite/views/staff/tables/edit.py | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/pysite/views/staff/tables/edit.py b/pysite/views/staff/tables/edit.py new file mode 100644 index 00000000..b70bc20e --- /dev/null +++ b/pysite/views/staff/tables/edit.py @@ -0,0 +1,110 @@ +import json + +from flask import redirect, request, url_for +from werkzeug.exceptions import BadRequest, NotFound + +from pysite.base_route import RouteView +from pysite.constants import TABLE_MANAGER_ROLES +from pysite.decorators import csrf, require_roles +from pysite.mixins import DBMixin +from pysite.tables import TABLES + + +class TableEditView(RouteView, DBMixin): + path = "/tables/<table>/edit" + name = "tables.edit" + + @require_roles(*TABLE_MANAGER_ROLES) + def get(self, table): + obj = TABLES.get(table) + + if not obj: + # Unknown table + raise NotFound() + + if obj.locked: + return redirect(url_for("staff.tables.table", table=table, page=1), code=303) + + key = request.args.get("key") + + old_primary = None + + if key: + db_obj = self.db.get(table, key) + old_primary = key # Provide the current document's primary key, in case it's modified + + document = json.dumps( # Editor uses JSON + db_obj, + indent=4 + ) + else: + document = json.dumps( # Generate default document from key schema + {k: "" for k in obj.keys}, + indent=4 + ) + + return self.render( + "staff/tables/edit.html", table=table, primary_key=obj.primary_key, + document=document, old_primary=old_primary + ) + + @require_roles(*TABLE_MANAGER_ROLES) + @csrf + def post(self, table): + obj = TABLES.get(TABLES) + + if not obj: + # Unknown table + raise NotFound() + + if obj.locked: + raise BadRequest() + + data = request.form.get("json") + old_primary = request.form.get("old_primary") + + if not data: + # No data given (for some reason) + document = json.dumps( + {k: "" for k in obj.keys}, + indent=4 + ) + + return self.render( + "staff/tables/edit.html", table=table, primary_key=obj.primary_key, document=document, + message="Please provide some data to save", old_primary=old_primary + ) + + try: + data = json.loads(data) + except json.JSONDecodeError as e: + # Invalid JSON + return self.render( + "staff/tables/edit.html", table=table, primary_key=obj.primary_key, document=data, + message=f"Invalid JSON, please try again: {e}", old_primary=old_primary + ) + + if not data[obj.primary_key]: + # No primary key value provided + return self.render( + "staff/tables/edit.html", table=table, primary_key=obj.primary_key, document=data, + message=f"Please provide a value for the primary key: {obj.primary_key}", old_primary=old_primary + ) + + if old_primary is None: + self.db.insert( # This is a new object, so just insert it + table, data + ) + elif old_primary == data[obj.primary_key]: + self.db.insert( # This is an update without a primary key change, replace the whole document + table, data, conflict="replace" + ) + else: + self.db.delete( # This is a primary key change, so we need to remove the old object + table, old_primary + ) + self.db.insert( + table, data, + ) + + return redirect(url_for("staff.tables.table", table=table, page=1), code=303) |