diff --git a/oshipka/persistance/__init__.py b/oshipka/persistance/__init__.py index 9808895..5a2c618 100644 --- a/oshipka/persistance/__init__.py +++ b/oshipka/persistance/__init__.py @@ -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) diff --git a/oshipka/search.py b/oshipka/search.py deleted file mode 100644 index 9e564ce..0000000 --- a/oshipka/search.py +++ /dev/null @@ -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'] diff --git a/oshipka/webapp/templates/delete_instance.html b/oshipka/webapp/templates/delete_instance.html index c29fb7b..8adee59 100644 --- a/oshipka/webapp/templates/delete_instance.html +++ b/oshipka/webapp/templates/delete_instance.html @@ -1,9 +1,9 @@ {% extends "layout.html" %} {% block content %} -

Delete {{ model_name }}:{{ instance.id }} ?

-
- +

Delete {{ model_view.model_name }}:{{ instance.id }} ?

+ +
Back diff --git a/oshipka/webapp/views.py b/oshipka/webapp/views.py index 5248f70..551303a 100644 --- a/oshipka/webapp/views.py +++ b/oshipka/webapp/views.py @@ -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 = '/{}/'.format(self.model_name_pl) + url_args = dict( + rule='/{}//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 = '/{}//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='/{}//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 = '/{}//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='/{}//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): diff --git a/vm_gen/templates/_hooks.py b/vm_gen/templates/_hooks.py index a3e24fc..09a6e32 100644 --- a/vm_gen/templates/_hooks.py +++ b/vm_gen/templates/_hooks.py @@ -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, +) diff --git a/vm_gen/templates/html/_create.html b/vm_gen/templates/html/_create.html index 063300e..9df14f0 100644 --- a/vm_gen/templates/html/_create.html +++ b/vm_gen/templates/html/_create.html @@ -1,11 +1,16 @@ -

Create [[ name ]]

[%- for column in columns %] - : - + : + [%- if column.type in ['relationship'] %] + + [%- else %] + + [%- endif %] [%- endfor %]
\ No newline at end of file diff --git a/vm_gen/templates/html/_get.html b/vm_gen/templates/html/_get.html index 10edc07..e69de29 100644 --- a/vm_gen/templates/html/_get.html +++ b/vm_gen/templates/html/_get.html @@ -1,3 +0,0 @@ -

{% include "[[ name|camel_to_snake ]]/_title.html" %}

-edit | -delete \ No newline at end of file diff --git a/vm_gen/templates/html/_list.html b/vm_gen/templates/html/_list.html index 7d0c018..70a5b4f 100644 --- a/vm_gen/templates/html/_list.html +++ b/vm_gen/templates/html/_list.html @@ -1,6 +1,3 @@ -

[[ name|pluralize ]]

-Create -
{% for instance in instances %}
  • diff --git a/vm_gen/templates/html/_search.html b/vm_gen/templates/html/_search.html new file mode 100644 index 0000000..70a5b4f --- /dev/null +++ b/vm_gen/templates/html/_search.html @@ -0,0 +1,11 @@ +{% for instance in instances %} +
  • + + {% include "[[ name|camel_to_snake ]]/_title.html" %} + | + [ + e | + x + ] +
  • +{% endfor %} \ No newline at end of file diff --git a/vm_gen/templates/html/_edit.html b/vm_gen/templates/html/_update.html similarity index 89% rename from vm_gen/templates/html/_edit.html rename to vm_gen/templates/html/_update.html index d3eab1c..d167665 100644 --- a/vm_gen/templates/html/_edit.html +++ b/vm_gen/templates/html/_update.html @@ -1,4 +1,3 @@ -

    Edit {% include "[[ name|camel_to_snake ]]/_title.html" %}

    [%- for column in columns %] diff --git a/vm_gen/templates/html/create.html b/vm_gen/templates/html/create.html index ac7fe3b..3c7d996 100644 --- a/vm_gen/templates/html/create.html +++ b/vm_gen/templates/html/create.html @@ -1,5 +1,6 @@ {% extends "layout.html" %} {% block content %} +

    Create [[ name ]]

    {% include "[[ name|camel_to_snake ]]/_create.html" %} {% endblock %} \ No newline at end of file diff --git a/vm_gen/templates/html/edit.html b/vm_gen/templates/html/edit.html deleted file mode 100644 index a0dadea..0000000 --- a/vm_gen/templates/html/edit.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "layout.html" %} - -{% block content %} - {% include "[[ name|camel_to_snake ]]/_edit.html" %} -{% endblock %} \ No newline at end of file diff --git a/vm_gen/templates/html/get.html b/vm_gen/templates/html/get.html index f8ee868..f838708 100644 --- a/vm_gen/templates/html/get.html +++ b/vm_gen/templates/html/get.html @@ -1,5 +1,9 @@ {% extends "layout.html" %} {% block content %} + list | +

    {% include "[[ name|camel_to_snake ]]/_title.html" %}

    + edit | + delete {% include "[[ name|camel_to_snake ]]/_get.html" %} {% endblock %} \ No newline at end of file diff --git a/vm_gen/templates/html/list.html b/vm_gen/templates/html/list.html index ec231bd..458bc63 100644 --- a/vm_gen/templates/html/list.html +++ b/vm_gen/templates/html/list.html @@ -1,5 +1,8 @@ {% extends "layout.html" %} {% block content %} +

    [[ name|pluralize ]]

    + Create +
    {% include "[[ name|camel_to_snake ]]/_list.html" %} {% endblock %} \ No newline at end of file diff --git a/vm_gen/templates/html/search.html b/vm_gen/templates/html/search.html new file mode 100644 index 0000000..a12962a --- /dev/null +++ b/vm_gen/templates/html/search.html @@ -0,0 +1,8 @@ +{% extends "layout.html" %} + +{% block content %} +

    Search results for [[ name|pluralize ]]

    + Create +
    + {% include "[[ name|camel_to_snake ]]/_search.html" %} +{% endblock %} \ No newline at end of file diff --git a/vm_gen/templates/html/update.html b/vm_gen/templates/html/update.html new file mode 100644 index 0000000..77c00a4 --- /dev/null +++ b/vm_gen/templates/html/update.html @@ -0,0 +1,6 @@ +{% extends "layout.html" %} + +{% block content %} +

    Edit {% include "[[ name|camel_to_snake ]]/_title.html" %}

    + {% include "[[ name|camel_to_snake ]]/_update.html" %} +{% endblock %} \ No newline at end of file diff --git a/vm_gen/templates/model_py b/vm_gen/templates/model_py index fb12075..be8d234 100644 --- a/vm_gen/templates/model_py +++ b/vm_gen/templates/model_py @@ -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 %] \ No newline at end of file diff --git a/vm_gen/templates/routes_py b/vm_gen/templates/routes_py index 8d68dc5..e8bddcd 100644 --- a/vm_gen/templates/routes_py +++ b/vm_gen/templates/routes_py @@ -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)