async def render_model_view(request: Request, model_id: Text) -> HTTPResponse: """ render model data view """ model_data = cfg.models[model_id] columns_names = model_data["columns_names"] table_name = get_table_name(model_id) model = cfg.app.db.tables[table_name] query = cfg.app.db.select([model]) columns_data = model_data["columns_data"] try: rows = await query.gino.all() except asyncpg.exceptions.UndefinedTableError: await cfg.app.db.gino.create_all(tables=[model]) rows = await query.gino.all() output = [] for row in rows: row = {columns_names[num]: field for num, field in enumerate(row)} row["_id"] = create_obj_id_for_query( get_obj_id_from_row(model_data, row)) for index in cfg.models[model_id]["hashed_indexes"]: row[columns_names[index]] = "*************" output.append(row) output = output[::-1] _response = cfg.jinja.render( "model_view.html", request, model=model_id, columns=columns_data_for_ui(columns_data, model_data), model_data=output, unique=cfg.models[model_id]["identity"], ) return _response
async def create_or_update(row: Dict, model_id: Text) -> Tuple: try: model_data = cfg.models[model_id] row = prepare_request_params(row, model_id, model_data) obj = (await model_data["model"].create(**row)).to_dict() obj_id = get_obj_id_from_row(model_data, obj) return obj_id, None, None except asyncpg.exceptions.UniqueViolationError as e: if cfg.csv_update_existed: obj_id = prepare_request_params( get_obj_id_from_row(model_data, row), model_id, model_data) obj = await get_by_params(obj_id, model_data["model"]) await obj.update(**row).apply() return None, obj_id, None else: return None, None, (row, e.args) except Exception as e: return None, None, (row, e.args)
async def model_edit_post(request, model_id): model_data = cfg.models[model_id] model = model_data["model"] columns_data = model_data["columns_data"] previous_id: Dict = utils.extract_obj_id_from_query( dict(request.query_args)["_id"]) previous_id: Dict = utils.correct_types(previous_id, columns_data, no_default=True) request_params = { key: request.form[key][0] if request.form[key][0] != "None" else None for key in request.form } request_params = utils.prepare_request_params(request_params, model_id, model_data) try: if not model_data["identity"]: old_obj = previous_id await update_all_by_params(request_params, previous_id, model) obj = request_params else: obj = await get_by_params(previous_id, model) old_obj = obj.to_dict() await obj.update(**request_params).apply() obj = obj.to_dict() changes = utils.get_changes(old_obj, obj) new_obj_id = utils.get_obj_id_from_row(model_data, request_params, previous_id) message = f"Object with id {previous_id} was updated." if changes: message += f'Changes: from {changes["from"]} to {changes["to"]}' request.ctx.flash(message, "success") log_history_event(request, message, previous_id) except asyncpg.exceptions.ForeignKeyViolationError as e: request.ctx.flash( f"ForeignKey error. " f"Impossible to edit field for row {previous_id}, " f"because exists objects that depend on it. {e}", "error", ) except asyncpg.exceptions.UniqueViolationError: request.ctx.flash( f"{model_id.capitalize()} with such id already exists", "error") except asyncpg.exceptions.NotNullViolationError as e: column = e.args[0].split("column")[1].split("violates")[0] request.ctx.flash(f"Field {column} cannot be null", "error") return await render_add_or_edit_form(request, model_id, new_obj_id)
async def model_delete(request, model_id): """ route for delete item per row """ model_data = cfg.models[model_id] model = model_data["model"] request_params = {key: request.form[key][0] for key in request.form} obj_id = utils.get_obj_id_from_row(model_data, request_params) try: if not model_data["identity"]: await delete_all_by_params(obj_id, model) else: obj = await get_by_params(obj_id, model) await obj.delete() message = f"Object with {obj_id} was deleted" flash_message = (message, "success") log_history_event(request, message, obj_id) except asyncpg.exceptions.ForeignKeyViolationError as e: flash_message = (str(e.args), "error") return await model_view_table(request, model_id, flash_message)
async def model_add(request, model_id): model_data = cfg.models[model_id] request_params = {key: request.form[key][0] for key in request.form} request_params = utils.prepare_request_params(request_params, model_id, model_data) not_filled = [ x for x in model_data["required_columns"] if x not in request_params ] if not_filled: request.ctx.flash(f"Fields {not_filled} required. Please fill it", "error") else: try: obj = await model_data["model"].create(**request_params) obj_id = utils.get_obj_id_from_row(model_data, obj.to_dict()) message = f"Object with {obj_id} was added." request.ctx.flash(message, "success") log_history_event(request, message, obj_id) except ( asyncpg.exceptions.StringDataRightTruncationError, ValueError, asyncpg.exceptions.ForeignKeyViolationError, ) as e: request.ctx.flash(e.args, "error") except asyncpg.exceptions.UniqueViolationError: request.ctx.flash( f"{model_id.capitalize()} with such id already exists", "error") except asyncpg.exceptions.NotNullViolationError as e: column = e.args[0].split("column")[1].split("violates")[0] request.ctx.flash(f"Field {column} cannot be null", "error") except asyncpg.exceptions.UndefinedTableError: request.ctx.flash( f"Somebody stole the table. Table {model_id} does not exist", "error") return await render_add_or_edit_form(request, model_id)