fix with view_context
This commit is contained in:
parent
958cde4baf
commit
cf4ffc861a
@ -23,7 +23,6 @@ from sqlalchemy.orm.collections import InstrumentedList
|
||||
from sqlalchemy_utils import Choice
|
||||
from tww.lib import solve_query, resolve_timezone, dt_tz_translation, time_ago
|
||||
from whooshalchemy import IndexService
|
||||
from oshipka.search import add_to_index, remove_from_index, query_index
|
||||
from oshipka.util.strings import camel_case_to_snake_case
|
||||
|
||||
db = SQLAlchemy()
|
||||
@ -221,11 +220,17 @@ def register_filters(app):
|
||||
class Proxy(object):
|
||||
def __init__(self, proxied):
|
||||
self.proxied = proxied
|
||||
self.searchables = []
|
||||
|
||||
|
||||
index_service = Proxy(None)
|
||||
|
||||
|
||||
def register_index_svc():
|
||||
for searchable in index_service.searchables:
|
||||
index_service.proxied.register_class(searchable)
|
||||
|
||||
|
||||
def init_db(app):
|
||||
rv = False
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = SQLALCHEMY_DATABASE_URI
|
||||
@ -253,6 +258,7 @@ def init_db(app):
|
||||
rv = True
|
||||
global index_service
|
||||
index_service.proxied = IndexService(config=app.config, session=db.session)
|
||||
register_index_svc()
|
||||
return rv
|
||||
|
||||
|
||||
@ -280,46 +286,3 @@ def populate_static(app):
|
||||
instance = model(**row)
|
||||
db.session.add(instance)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
class SearchableMixin(object):
|
||||
@classmethod
|
||||
def search(cls, expression, page, per_page):
|
||||
ids, total = query_index(cls.__tablename__, expression, page, per_page)
|
||||
if total == 0:
|
||||
return cls.query.filter_by(id=0), 0
|
||||
when = []
|
||||
for i in range(len(ids)):
|
||||
when.append((ids[i], i))
|
||||
return cls.query.filter(cls.id.in_(ids)).order_by(
|
||||
db.case(when, value=cls.id)), total
|
||||
|
||||
@classmethod
|
||||
def before_commit(cls, session):
|
||||
session._changes = {
|
||||
'add': list(session.new),
|
||||
'update': list(session.dirty),
|
||||
'delete': list(session.deleted)
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def after_commit(cls, session):
|
||||
for obj in session._changes['add']:
|
||||
if isinstance(obj, SearchableMixin):
|
||||
add_to_index(obj.__tablename__, obj)
|
||||
for obj in session._changes['update']:
|
||||
if isinstance(obj, SearchableMixin):
|
||||
add_to_index(obj.__tablename__, obj)
|
||||
for obj in session._changes['delete']:
|
||||
if isinstance(obj, SearchableMixin):
|
||||
remove_from_index(obj.__tablename__, obj)
|
||||
session._changes = None
|
||||
|
||||
@classmethod
|
||||
def reindex(cls):
|
||||
for obj in cls.query:
|
||||
add_to_index(cls.__tablename__, obj)
|
||||
|
||||
|
||||
db.event.listen(db.session, 'before_commit', SearchableMixin.before_commit)
|
||||
db.event.listen(db.session, 'after_commit', SearchableMixin.after_commit)
|
||||
|
@ -1,27 +0,0 @@
|
||||
from flask import current_app
|
||||
|
||||
|
||||
def add_to_index(index, model):
|
||||
if not hasattr(current_app, 'elasticsearch'):
|
||||
return
|
||||
payload = {}
|
||||
for field in model.__searchable__:
|
||||
payload[field] = getattr(model, field)
|
||||
current_app.elasticsearch.index(index=index, id=model.id, body=payload)
|
||||
|
||||
|
||||
def remove_from_index(index, model):
|
||||
if not hasattr(current_app, 'elasticsearch'):
|
||||
return
|
||||
current_app.elasticsearch.delete(index=index, id=model.id)
|
||||
|
||||
|
||||
def query_index(index, query, page, per_page):
|
||||
if not hasattr(current_app, 'elasticsearch'):
|
||||
return [], 0
|
||||
search = current_app.elasticsearch.search(
|
||||
index=index,
|
||||
body={'query': {'multi_match': {'query': query, 'fields': ['*']}},
|
||||
'from': (page - 1) * per_page, 'size': per_page})
|
||||
ids = [int(hit['_id']) for hit in search['hits']['hits']]
|
||||
return ids, search['hits']['total']['value']
|
@ -1,9 +1,9 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Delete {{ model_name }}:{{ instance.id }} ?</h1>
|
||||
<form action="{{ url_for('delete_' + model_name, uuid=instance.uuid) }}" method="post">
|
||||
<input type="hidden" value="{{ request.args.next or url_for('list_' + model_name) }}" name="_next"/>
|
||||
<h1>Delete {{ model_view.model_name }}:{{ instance.id }} ?</h1>
|
||||
<form action="{{ url_for('delete_' + model_view.model_name, uuid=instance.uuid) }}" method="post">
|
||||
<input type="hidden" value="{{ request.args.next or url_for('list_' + model_view.model_name) }}" name="_next"/>
|
||||
<input type="submit"/>
|
||||
</form>
|
||||
<a href="{{ request.args.next }}">Back</a>
|
||||
|
@ -1,185 +1,173 @@
|
||||
from functools import wraps
|
||||
from uuid import uuid4
|
||||
|
||||
import inflect
|
||||
from flask import flash, render_template, redirect, request, url_for
|
||||
from flask import flash, render_template, redirect, request, url_for, jsonify
|
||||
|
||||
from oshipka.persistance import db
|
||||
from oshipka.util.strings import camel_case_to_snake_case
|
||||
|
||||
|
||||
def get_instance(model_view, uuid):
|
||||
model = model_view.model
|
||||
if uuid.isdigit():
|
||||
instance = model.query.filter_by(id=uuid).first()
|
||||
def default_get_args_func(view_context):
|
||||
view_context.serialized_args = request.args
|
||||
|
||||
|
||||
def default_get_form_func(vc):
|
||||
vc.redirect_next = request.form.get('_next')
|
||||
vc.serialized_args = dict(filter(lambda k: not k[0].startswith("_"), dict(request.form).items()))
|
||||
to_delete = []
|
||||
for key, value in vc.serialized_args.items():
|
||||
if key.endswith('_id'):
|
||||
if value in ['']:
|
||||
to_delete.append(key)
|
||||
else:
|
||||
vc.serialized_args[key] = int(value)
|
||||
for key in to_delete:
|
||||
del vc.serialized_args[key]
|
||||
|
||||
|
||||
def default_jsonify_func(vc):
|
||||
if type(vc.instances) is list:
|
||||
return jsonify([instance.serialize() for instance in vc.instances])
|
||||
return jsonify(vc.instances.serialize())
|
||||
|
||||
|
||||
def default_redirect_func(vc):
|
||||
return redirect(vc.redirect_next or request.referrer or url_for('home'))
|
||||
|
||||
|
||||
def default_get_func(vc):
|
||||
model = vc.model_view.model
|
||||
uuid = vc.url_args.get('uuid')
|
||||
if uuid and vc.url_args.get('uuid').isdigit():
|
||||
vc.instances = model.query.filter_by(id=uuid).all()
|
||||
else:
|
||||
instance = model.query.filter_by(uuid=uuid).first()
|
||||
if not instance:
|
||||
flash("No {}:{}".format(model_view.model_name, uuid))
|
||||
return instance
|
||||
vc.instances = model.query.filter_by(uuid=uuid).all()
|
||||
if not vc.instances:
|
||||
flash("No {}:{}".format(vc.model_view.model_name, uuid))
|
||||
|
||||
|
||||
def list_view(model_view, template_func=None, template_ctx_func=None, args_process_func=None,
|
||||
list_func=None, post_list_func=None, **kwargs):
|
||||
def inner():
|
||||
serialized_args = request.args
|
||||
serialized_args = args_process_func(serialized_args) if args_process_func else serialized_args
|
||||
instances = None
|
||||
if list_func is not None:
|
||||
instances = list_func(model_view, serialized_args)
|
||||
if instances is None:
|
||||
instances = model_view.model.query.all()
|
||||
if post_list_func is not None:
|
||||
instances = post_list_func(instances)
|
||||
template = template_func(instances) if template_func else None
|
||||
if not template:
|
||||
template = "{}/list.html".format(model_view.model_name)
|
||||
template_ctx = template_ctx_func(instances) if template_ctx_func else {}
|
||||
return render_template(template, instances=instances, **template_ctx)
|
||||
|
||||
return inner
|
||||
def default_list_args_get_func(vc):
|
||||
vc.serialized_args = request.args
|
||||
|
||||
|
||||
def get_view(model_view, template_func=None, template_ctx_func=None, args_process_func=None,
|
||||
get_func=None, post_get_func=None, **kwargs):
|
||||
def inner(uuid):
|
||||
serialized_args = request.args
|
||||
serialized_args = args_process_func(serialized_args) if args_process_func else serialized_args
|
||||
instance = None
|
||||
if get_func is not None:
|
||||
instance = get_func(model_view, uuid, serialized_args)
|
||||
if instance is not None:
|
||||
instance = instance[0]
|
||||
if instance is None:
|
||||
instance = get_instance(model_view, uuid)
|
||||
if post_get_func is not None:
|
||||
instance = post_get_func(instance)
|
||||
template = template_func(instance) if template_func else None
|
||||
if not template:
|
||||
template = "{}/get.html".format(model_view.model_name)
|
||||
template_ctx = template_ctx_func(instance) if template_ctx_func else {}
|
||||
return render_template(template, instance=instance, **template_ctx)
|
||||
|
||||
return inner
|
||||
def default_list_func(vc):
|
||||
vc.instances = vc.model_view.model.query.all()
|
||||
|
||||
|
||||
def serialize_form():
|
||||
return dict(filter(lambda k: not k[0].startswith("__"), dict(request.form).items()))
|
||||
def default_search_func(vc):
|
||||
q = vc.serialized_args.get('q')
|
||||
if hasattr(vc.model_view.model, 'search_query'):
|
||||
vc.instances = vc.model_view.model.search_query("{q}".format(q=q)).all()
|
||||
|
||||
|
||||
def update_view(model_view, template_func=None, template_ctx_func=None, args_process_func=None,
|
||||
should_update_func=None, post_add=None, post_commit=None, **kwargs):
|
||||
def inner(uuid):
|
||||
instance = get_instance(model_view, uuid)
|
||||
if not instance:
|
||||
return redirect(request.referrer or url_for('home'))
|
||||
def default_create_func(vc):
|
||||
instance = vc.model_view.model(**vc.serialized_args)
|
||||
db.session.add(instance)
|
||||
vc.instances = [instance]
|
||||
|
||||
|
||||
def default_update_func(vc):
|
||||
instance = vc.instances[0]
|
||||
for k, v in vc.serialized_args.items():
|
||||
setattr(instance, k, v)
|
||||
db.session.add(instance)
|
||||
|
||||
|
||||
def default_delete_func(vc):
|
||||
instance = vc.instances[0]
|
||||
db.session.delete(instance)
|
||||
|
||||
|
||||
def default_render_func(vc):
|
||||
if len(vc.instances) == 1:
|
||||
vc.template_ctx['instance'] = vc.instances[0]
|
||||
vc.template_ctx['instances'] = vc.instances
|
||||
vc.template_ctx['model_view'] = vc.model_view
|
||||
return render_template(vc.template, **vc.template_ctx)
|
||||
|
||||
|
||||
def default_commit_func(vc):
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def default_none_func(vc):
|
||||
pass
|
||||
|
||||
|
||||
class ViewContext(object):
|
||||
def __init__(self, args_get_func=None, args_process_func=None,
|
||||
filter_func=None, redirect_func=None,
|
||||
should_execute_func=None, execute_func=None, post_execute_func=None,
|
||||
commit_func=None, post_commit_func=None,
|
||||
jsonify_func=None, render_func=None, template_func=None, template_ctx_func=None,
|
||||
should_redirect_no_instances_func=None,
|
||||
should_redirect_at_end_func=None,
|
||||
json=False, **kwargs):
|
||||
self.args_get_func = args_get_func or default_get_args_func
|
||||
self.args_process_func = args_process_func or default_none_func
|
||||
self.filter_func = filter_func or default_none_func
|
||||
self.should_redirect_no_instances_func = should_redirect_no_instances_func or default_none_func
|
||||
self.redirect_func = redirect_func or default_redirect_func
|
||||
self.should_execute_func = should_execute_func or default_none_func
|
||||
self.execute_func = execute_func or default_none_func
|
||||
self.post_execute_func = post_execute_func or default_none_func
|
||||
self.commit_func = commit_func or default_commit_func
|
||||
self.post_commit_func = post_commit_func or default_none_func
|
||||
self.jsonify_func = jsonify_func or default_jsonify_func
|
||||
self.render_func = render_func or default_render_func
|
||||
self.template_func = template_func or default_none_func
|
||||
self.template_ctx_func = template_ctx_func or default_none_func
|
||||
self.should_redirect_at_end_func = should_redirect_at_end_func or default_none_func
|
||||
self.json = json
|
||||
|
||||
self.serialized_args = {}
|
||||
self.url_args = {}
|
||||
self.instances = []
|
||||
self.should_execute = True
|
||||
self.should_redirect_at_end = True
|
||||
self.template = None
|
||||
self.template_ctx = {}
|
||||
self.model_view = None
|
||||
self.redirect_next = None
|
||||
|
||||
|
||||
def create_view(model_view, view_context, is_json=False, **kwargs):
|
||||
view_context.model_view = model_view
|
||||
|
||||
def return_json_or_template():
|
||||
if is_json:
|
||||
return view_context.jsonify_func(view_context)
|
||||
view_context.template_func(view_context)
|
||||
view_context.template_ctx_func(view_context)
|
||||
return view_context.render_func(view_context)
|
||||
|
||||
def inner(**kwargs):
|
||||
view_context.url_args = kwargs
|
||||
view_context.args_get_func(view_context)
|
||||
view_context.args_process_func(view_context)
|
||||
|
||||
view_context.filter_func(view_context)
|
||||
if not view_context.instances:
|
||||
if view_context.should_redirect_no_instances_func(view_context):
|
||||
return view_context.redirect_func(view_context)
|
||||
|
||||
if request.method == "GET":
|
||||
template = template_func(instance) if template_func else None
|
||||
if not template:
|
||||
template = "{}/edit.html".format(model_view.model_name)
|
||||
template_ctx = template_ctx_func(instance) if template_ctx_func else {}
|
||||
return render_template(template, instance=instance, **template_ctx)
|
||||
serialized_form = serialize_form()
|
||||
return return_json_or_template()
|
||||
|
||||
_next = serialized_form.pop('_next') if '_next' in serialized_form else None
|
||||
serialized_form = args_process_func(serialized_form) if args_process_func else serialized_form
|
||||
if should_update_func is not None:
|
||||
should_update, msg = should_update_func(instance, serialized_form)
|
||||
else:
|
||||
should_update, msg = True, ""
|
||||
if not should_update:
|
||||
if msg:
|
||||
flash(msg)
|
||||
return redirect(_next or request.referrer or url_for('home'))
|
||||
for k, v in serialized_form.items():
|
||||
setattr(instance, k, v)
|
||||
view_context.should_execute_func(view_context)
|
||||
if not view_context.should_execute:
|
||||
return view_context.redirect_func(view_context)
|
||||
|
||||
db.session.add(instance)
|
||||
if post_add is not None:
|
||||
post_add(instance)
|
||||
view_context.execute_func(view_context)
|
||||
view_context.post_execute_func(view_context)
|
||||
view_context.commit_func(view_context)
|
||||
view_context.post_commit_func(view_context)
|
||||
|
||||
db.session.commit()
|
||||
if post_commit is not None:
|
||||
post_commit(instance)
|
||||
flash("Updated {}:{}".format(model_view.model_name, id))
|
||||
return redirect(_next or request.referrer or url_for('home'))
|
||||
view_context.should_redirect_at_end_func(view_context)
|
||||
if view_context.should_redirect_at_end:
|
||||
return view_context.redirect_func(view_context)
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
def create_view(model_view, template_func=None, template_ctx_func=None, args_process_func=None,
|
||||
should_func=None, post_add=None, post_commit=None):
|
||||
def inner():
|
||||
if request.method == "GET":
|
||||
template = template_func() if template_func else None
|
||||
if not template:
|
||||
template = "{}/create.html".format(model_view.model_name)
|
||||
template_ctx = template_ctx_func() if template_ctx_func else {}
|
||||
return render_template(template, **template_ctx)
|
||||
serialized_form = serialize_form()
|
||||
|
||||
_next = serialized_form.pop('_next') if '_next' in serialized_form else None
|
||||
serialized_form = args_process_func(serialized_form) if args_process_func else serialized_form
|
||||
serialized_form['uuid'] = str(uuid4())
|
||||
|
||||
if should_func is not None:
|
||||
should_create, msg = should_func(serialized_form)
|
||||
else:
|
||||
should_create, msg = True, ""
|
||||
if not should_create:
|
||||
if msg:
|
||||
flash(msg)
|
||||
return redirect(_next or request.referrer or url_for('home'))
|
||||
instance = model_view.model(**serialized_form)
|
||||
db.session.add(instance)
|
||||
if post_add is not None:
|
||||
post_add(instance)
|
||||
|
||||
db.session.commit()
|
||||
if post_commit is not None:
|
||||
post_commit(instance)
|
||||
flash("Created {}".format(model_view.model_name))
|
||||
return redirect(_next or request.referrer or url_for('home'))
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
def delete_view(model_view, template_func=None, template_ctx_func=None, args_process_func=None,
|
||||
should_func=None, post_delete=None, post_commit=None, **kwargs):
|
||||
def inner(uuid):
|
||||
instance = get_instance(model_view, uuid)
|
||||
if not instance:
|
||||
return redirect(request.referrer or url_for('home'))
|
||||
if request.method == "GET":
|
||||
template = template_func(instance) if template_func else None
|
||||
if not template:
|
||||
template = "delete_instance.html"
|
||||
template_ctx = template_ctx_func(instance) if template_ctx_func else {}
|
||||
return render_template(template,
|
||||
instance=instance,
|
||||
model_name=model_view.model_name,
|
||||
**template_ctx)
|
||||
|
||||
serialized_form = serialize_form()
|
||||
serialized_form = args_process_func(serialized_form) if args_process_func else serialized_form
|
||||
_next = serialized_form.pop('_next') if '_next' in serialized_form else None
|
||||
if should_func is not None:
|
||||
should_delete, msg = should_func(instance, serialized_form)
|
||||
else:
|
||||
should_delete, msg = True, ""
|
||||
if not should_delete:
|
||||
if msg:
|
||||
flash(msg)
|
||||
return redirect(_next or request.referrer or url_for('home'))
|
||||
db.session.delete(instance)
|
||||
if post_delete is not None:
|
||||
post_delete(instance)
|
||||
|
||||
db.session.commit()
|
||||
if post_commit is not None:
|
||||
post_commit(instance)
|
||||
flash("Deleted {}:{}".format(model_view.model_name, uuid))
|
||||
return redirect(_next or request.referrer or url_for('home'))
|
||||
return return_json_or_template()
|
||||
|
||||
return inner
|
||||
|
||||
@ -194,36 +182,71 @@ class ModelView(object):
|
||||
self.model_name = camel_case_to_snake_case(model.__name__)
|
||||
self.model_name_pl = p.plural(self.model_name)
|
||||
|
||||
def register_create(self, **kwargs):
|
||||
url = '/{}/create'.format(self.model_name_pl)
|
||||
self.app.add_url_rule(url, methods=["GET", "POST"],
|
||||
endpoint='create_{}'.format(self.model_name),
|
||||
view_func=create_view(self, **kwargs))
|
||||
|
||||
def register_list(self, **kwargs):
|
||||
url = '/{}'.format(self.model_name_pl)
|
||||
self.app.add_url_rule(url,
|
||||
'list_{}'.format(self.model_name),
|
||||
list_view(self, **kwargs))
|
||||
def _register_rule(self, url_args, **kwargs):
|
||||
url = url_args.pop('rule')
|
||||
api_url = '/api{}'.format(url)
|
||||
endpoint = url_args.pop('endpoint')
|
||||
api_endpoint = 'api_{}'.format(endpoint)
|
||||
view_func = url_args.pop('view_func')
|
||||
self.app.add_url_rule(rule=url, endpoint=endpoint,
|
||||
view_func=view_func(self, **kwargs), **url_args)
|
||||
kwargs['is_json'] = True
|
||||
self.app.add_url_rule(rule=api_url, endpoint=api_endpoint,
|
||||
view_func=view_func(self, **kwargs), **url_args)
|
||||
|
||||
def register_get(self, **kwargs):
|
||||
url = '/{}/<uuid>'.format(self.model_name_pl)
|
||||
url_args = dict(
|
||||
rule='/{}/<uuid>/get'.format(self.model_name_pl),
|
||||
methods=["GET"],
|
||||
endpoint='get_{}'.format(self.model_name),
|
||||
view_func=create_view,
|
||||
)
|
||||
self._register_rule(url_args, **kwargs)
|
||||
|
||||
self.app.add_url_rule(url,
|
||||
'get_{}'.format(self.model_name),
|
||||
get_view(self, **kwargs))
|
||||
def register_list(self, **kwargs):
|
||||
url_args = dict(
|
||||
rule='/{}/list'.format(self.model_name_pl),
|
||||
methods=["GET"],
|
||||
endpoint='list_{}'.format(self.model_name),
|
||||
view_func=create_view,
|
||||
)
|
||||
self._register_rule(url_args, **kwargs)
|
||||
|
||||
def register_create(self, **kwargs):
|
||||
url_args = dict(
|
||||
rule='/{}/create'.format(self.model_name_pl),
|
||||
methods=["GET", "POST"],
|
||||
endpoint='create_{}'.format(self.model_name),
|
||||
view_func=create_view,
|
||||
)
|
||||
self._register_rule(url_args, **kwargs)
|
||||
|
||||
def register_update(self, **kwargs):
|
||||
url = '/{}/<uuid>/edit'.format(self.model_name_pl)
|
||||
self.app.add_url_rule(url, methods=["GET", "POST"],
|
||||
endpoint='update_{}'.format(self.model_name),
|
||||
view_func=update_view(self, **kwargs))
|
||||
url_args = dict(
|
||||
rule='/{}/<uuid>/update'.format(self.model_name_pl),
|
||||
methods=["GET", "POST"],
|
||||
endpoint='update_{}'.format(self.model_name),
|
||||
view_func=create_view,
|
||||
)
|
||||
self._register_rule(url_args, **kwargs)
|
||||
|
||||
def register_delete(self, **kwargs):
|
||||
url = '/{}/<uuid>/delete'.format(self.model_name_pl)
|
||||
self.app.add_url_rule(url, methods=["GET", "POST"],
|
||||
endpoint='delete_{}'.format(self.model_name),
|
||||
view_func=delete_view(self, **kwargs))
|
||||
url_args = dict(
|
||||
rule='/{}/<uuid>/delete'.format(self.model_name_pl),
|
||||
methods=["GET", "POST"],
|
||||
endpoint='delete_{}'.format(self.model_name),
|
||||
view_func=create_view,
|
||||
)
|
||||
self._register_rule(url_args, **kwargs)
|
||||
|
||||
def register_search(self, **kwargs):
|
||||
url_args = dict(
|
||||
rule='/{}/search'.format(self.model_name_pl),
|
||||
methods=["GET"],
|
||||
endpoint='search_{}'.format(self.model_name),
|
||||
view_func=create_view,
|
||||
)
|
||||
self._register_rule(url_args, **kwargs)
|
||||
|
||||
|
||||
def catch_flash(f):
|
||||
|
@ -1,109 +1,62 @@
|
||||
def get_template_func(instance):
|
||||
return None
|
||||
from oshipka.webapp.views import ViewContext, default_get_args_func, default_get_func, default_list_func, \
|
||||
default_get_form_func, default_create_func, default_update_func, default_delete_func, default_search_func
|
||||
|
||||
|
||||
def get_templ_ctx_func(instance):
|
||||
rv = dict()
|
||||
return rv
|
||||
def get_template(vc):
|
||||
vc.template = "{}/get.html".format(vc.model_view.model_name)
|
||||
|
||||
|
||||
def get_func(model_view, uuid, serialized_args):
|
||||
"""Should return a list of one element (or [None] if element is none) or None if you want default behaviour"""
|
||||
return None
|
||||
def search_template(vc):
|
||||
vc.template = "{}/search.html".format(vc.model_view.model_name)
|
||||
|
||||
|
||||
def post_get_func(instance):
|
||||
return instance
|
||||
def list_template(vc):
|
||||
vc.template = "{}/list.html".format(vc.model_view.model_name)
|
||||
|
||||
|
||||
def list_template_func(instances):
|
||||
return None
|
||||
def create_template(vc):
|
||||
vc.template = "{}/create.html".format(vc.model_view.model_name)
|
||||
|
||||
|
||||
def list_templ_ctx_func(instances):
|
||||
rv = dict()
|
||||
return rv
|
||||
def update_template(vc):
|
||||
vc.template = "{}/update.html".format(vc.model_view.model_name)
|
||||
|
||||
|
||||
def list_func(model_view, serialized_args):
|
||||
"""Should return a list elements or None if you want default behaviour"""
|
||||
return None
|
||||
def delete_template(vc):
|
||||
vc.template = "delete_instance.html".format(vc.model_view.model_name)
|
||||
|
||||
|
||||
def post_list_func(instances):
|
||||
return instances
|
||||
get_view_context = ViewContext(
|
||||
filter_func=default_get_func,
|
||||
template_func=get_template,
|
||||
)
|
||||
|
||||
list_view_context = ViewContext(
|
||||
filter_func=default_list_func,
|
||||
template_func=list_template,
|
||||
)
|
||||
|
||||
def create_template_func():
|
||||
return None
|
||||
search_view_context = ViewContext(
|
||||
filter_func=default_search_func,
|
||||
template_func=list_template,
|
||||
)
|
||||
|
||||
create_view_context = ViewContext(
|
||||
args_get_func=default_get_form_func,
|
||||
template_func=create_template,
|
||||
execute_func=default_create_func,
|
||||
)
|
||||
|
||||
def create_templ_ctx_func():
|
||||
rv = dict()
|
||||
return rv
|
||||
update_view_context = ViewContext(
|
||||
args_get_func=default_get_form_func,
|
||||
filter_func=default_get_func,
|
||||
template_func=update_template,
|
||||
execute_func=default_update_func,
|
||||
)
|
||||
|
||||
|
||||
def create_args_process_func(serialized_form):
|
||||
return serialized_form
|
||||
|
||||
|
||||
def create_should_func(serialized_form):
|
||||
return True, ""
|
||||
|
||||
|
||||
def create_post_add_func(instance):
|
||||
pass
|
||||
|
||||
|
||||
def create_post_commit_func(instance):
|
||||
pass
|
||||
|
||||
|
||||
def update_template_func(instance):
|
||||
return None
|
||||
|
||||
|
||||
def update_templ_ctx_func(instance):
|
||||
rv = dict()
|
||||
return rv
|
||||
|
||||
|
||||
def update_args_process_func(serialized_form):
|
||||
return serialized_form
|
||||
|
||||
|
||||
def update_should_func(serialized_form):
|
||||
return True, ""
|
||||
|
||||
|
||||
def update_post_add_func(instance):
|
||||
pass
|
||||
|
||||
|
||||
def update_post_commit_func(instance):
|
||||
pass
|
||||
|
||||
|
||||
def delete_template_func(instance):
|
||||
return None
|
||||
|
||||
|
||||
def delete_templ_ctx_func(instance):
|
||||
rv = dict()
|
||||
return rv
|
||||
|
||||
|
||||
def delete_args_process_func(serialized_form):
|
||||
return serialized_form
|
||||
|
||||
|
||||
def delete_should_func(instance, serialized_form):
|
||||
return True, ""
|
||||
|
||||
|
||||
def delete_post_delete_func(instance):
|
||||
pass
|
||||
|
||||
|
||||
def delete_post_commit_func(instance):
|
||||
pass
|
||||
delete_view_context = ViewContext(
|
||||
args_get_func=default_get_form_func,
|
||||
filter_func=default_get_func,
|
||||
template_func=delete_template,
|
||||
execute_func=default_delete_func,
|
||||
)
|
||||
|
@ -1,11 +1,16 @@
|
||||
<h2>Create [[ name ]]</h2>
|
||||
<form action="{{ url_for('create_[[ name|camel_to_snake ]]') }}" method="post">
|
||||
<input type="hidden" name="_next" value="{{ url_for('list_[[ name|camel_to_snake ]]') }}"/>
|
||||
[%- for column in columns %]
|
||||
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
|
||||
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||
type="text" name="[[ column.name ]]" autocomplete="off"
|
||||
/>
|
||||
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
|
||||
[%- if column.type in ['relationship'] %]
|
||||
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||
type="number" name="[[ column.name ]]_id" autocomplete="off"
|
||||
/>
|
||||
[%- else %]
|
||||
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||
type="text" name="[[ column.name ]]" autocomplete="off"
|
||||
/>
|
||||
[%- endif %]
|
||||
[%- endfor %]
|
||||
<input type="submit">
|
||||
</form>
|
@ -1,3 +0,0 @@
|
||||
<h2>{% include "[[ name|camel_to_snake ]]/_title.html" %}</h2>
|
||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id) }}">edit</a> |
|
||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id) }}">delete</a>
|
@ -1,6 +1,3 @@
|
||||
<h2>[[ name|pluralize ]]</h2>
|
||||
<a href="{{ url_for('create_[[ name|camel_to_snake ]]') }}">Create</a>
|
||||
<br>
|
||||
{% for instance in instances %}
|
||||
<li>
|
||||
<a href="{{ url_for('get_[[ name|camel_to_snake ]]', uuid=instance.id) }}">
|
||||
|
11
vm_gen/templates/html/_search.html
Normal file
11
vm_gen/templates/html/_search.html
Normal file
@ -0,0 +1,11 @@
|
||||
{% for instance in instances %}
|
||||
<li>
|
||||
<a href="{{ url_for('get_[[ name|camel_to_snake ]]', uuid=instance.id) }}">
|
||||
{% include "[[ name|camel_to_snake ]]/_title.html" %}</a>
|
||||
|
|
||||
[
|
||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id) }}">e</a> |
|
||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id) }}">x</a>
|
||||
]
|
||||
</li>
|
||||
{% endfor %}
|
@ -1,4 +1,3 @@
|
||||
<h2>Edit {% include "[[ name|camel_to_snake ]]/_title.html" %}</h2>
|
||||
<form action="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id) }}" method="post">
|
||||
<input type="hidden" name="_next" value="{{ url_for('get_[[ name|camel_to_snake ]]', uuid=instance.id) }}"/>
|
||||
[%- for column in columns %]
|
@ -1,5 +1,6 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Create [[ name ]]</h2>
|
||||
{% include "[[ name|camel_to_snake ]]/_create.html" %}
|
||||
{% endblock %}
|
@ -1,5 +0,0 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
{% include "[[ name|camel_to_snake ]]/_edit.html" %}
|
||||
{% endblock %}
|
@ -1,5 +1,9 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<a href="{{ url_for('list_[[ name|camel_to_snake ]]', uuid=instance.id) }}">list</a> |
|
||||
<h2>{% include "[[ name|camel_to_snake ]]/_title.html" %}</h2>
|
||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id) }}">edit</a> |
|
||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id) }}">delete</a>
|
||||
{% include "[[ name|camel_to_snake ]]/_get.html" %}
|
||||
{% endblock %}
|
@ -1,5 +1,8 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>[[ name|pluralize ]]</h2>
|
||||
<a href="{{ url_for('create_[[ name|camel_to_snake ]]') }}">Create</a>
|
||||
<br>
|
||||
{% include "[[ name|camel_to_snake ]]/_list.html" %}
|
||||
{% endblock %}
|
8
vm_gen/templates/html/search.html
Normal file
8
vm_gen/templates/html/search.html
Normal file
@ -0,0 +1,8 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Search results for [[ name|pluralize ]]</h2>
|
||||
<a href="{{ url_for('create_[[ name|camel_to_snake ]]') }}">Create</a>
|
||||
<br>
|
||||
{% include "[[ name|camel_to_snake ]]/_search.html" %}
|
||||
{% endblock %}
|
6
vm_gen/templates/html/update.html
Normal file
6
vm_gen/templates/html/update.html
Normal file
@ -0,0 +1,6 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Edit {% include "[[ name|camel_to_snake ]]/_title.html" %}</h2>
|
||||
{% include "[[ name|camel_to_snake ]]/_update.html" %}
|
||||
{% endblock %}
|
@ -1,4 +1,4 @@
|
||||
from oshipka.persistance import db, ModelController
|
||||
from oshipka.persistance import db, ModelController, index_service
|
||||
|
||||
[%- if imports %]
|
||||
[%- for import in imports %]
|
||||
@ -10,4 +10,8 @@ from oshipka.persistance import db, ModelController
|
||||
[% include "_model_m_n_py" %]
|
||||
[%- else %]
|
||||
[% include "_model_py" %]
|
||||
[%- endif %]
|
||||
|
||||
[%- if searchable %]
|
||||
index_service.searchables.append([[ name ]])
|
||||
[%- endif %]
|
@ -9,39 +9,9 @@ from oshipka.webapp.views import ModelView
|
||||
from webapp.models import [[ name ]]
|
||||
from webapp.routes.[[ name|camel_to_snake ]]_hooks import *
|
||||
|
||||
ModelView(app, [[name]]).register_get(
|
||||
template_func=get_template_func,
|
||||
template_ctx_func=get_templ_ctx_func,
|
||||
get_func=get_func,
|
||||
post_get_func=post_get_func,
|
||||
)
|
||||
ModelView(app, [[name]]).register_list(
|
||||
template_func=list_template_func,
|
||||
template_ctx_func=list_templ_ctx_func,
|
||||
list_func=list_func,
|
||||
post_list_func=post_list_func,
|
||||
)
|
||||
ModelView(app, [[name]]).register_create(
|
||||
template_func=create_template_func,
|
||||
template_ctx_func=create_templ_ctx_func,
|
||||
args_process_func=create_args_process_func,
|
||||
should_func=create_should_func,
|
||||
post_add=create_post_add_func,
|
||||
post_commit=create_post_commit_func,
|
||||
)
|
||||
ModelView(app, [[name]]).register_update(
|
||||
template_func=update_template_func,
|
||||
template_ctx_func=update_templ_ctx_func,
|
||||
args_process_func=update_args_process_func,
|
||||
should_func=update_should_func,
|
||||
post_add=update_post_add_func,
|
||||
post_commit=update_post_commit_func,
|
||||
)
|
||||
ModelView(app, [[name]]).register_delete(
|
||||
template_func=delete_template_func,
|
||||
template_ctx_func=delete_templ_ctx_func,
|
||||
args_process_func=delete_args_process_func,
|
||||
should_func=delete_should_func,
|
||||
post_add=delete_post_delete_func,
|
||||
post_commit=delete_post_commit_func,
|
||||
)
|
||||
ModelView(app, [[name]]).register_get(view_context=get_view_context)
|
||||
ModelView(app, [[name]]).register_list(view_context=list_view_context)
|
||||
ModelView(app, [[name]]).register_search(view_context=search_view_context)
|
||||
ModelView(app, [[name]]).register_create(view_context=create_view_context)
|
||||
ModelView(app, [[name]]).register_update(view_context=update_view_context)
|
||||
ModelView(app, [[name]]).register_delete(view_context=delete_view_context)
|
||||
|
Loading…
Reference in New Issue
Block a user