diff --git a/bootstrap/webapp/templates/layout.html b/bootstrap/webapp/templates/layout.html index e148634..7a7b600 100644 --- a/bootstrap/webapp/templates/layout.html +++ b/bootstrap/webapp/templates/layout.html @@ -48,6 +48,16 @@ font-family: Open Sans, Arial sans-serif; font-size: 1em; box-sizing: border-box; + min-width: 300px; + } + + input[type=number] { + min-width: 70px; + width: 70px; + } + + select { + min-width: 300px; } .full-width { diff --git a/oshipka/webapp/views.py b/oshipka/webapp/views.py index a17c706..a33f3c5 100644 --- a/oshipka/webapp/views.py +++ b/oshipka/webapp/views.py @@ -1,3 +1,4 @@ +import importlib from functools import wraps import inflect @@ -6,15 +7,21 @@ 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 +webapp_models = importlib.import_module("webapp.models") + MODEL_VIEWS = dict() + 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())) + for k in request.form: + if k.startswith('_m_n_'): + vc.serialized_args[k] = request.form.getlist(k) + vc.serialized_args.update(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'): @@ -61,16 +68,43 @@ def default_search_func(vc): vc.instances = vc.model_view.model.search_query("{q}".format(q=q)).all() +def _filter_m_n(vc): + m_ns, to_delete = {}, [] + for k in vc.serialized_args: + if k.startswith('_m_n_'): + m_n_name = k.split('_m_n_')[1] + m_ns[m_n_name] = vc.serialized_args[k] + to_delete.append(k) + for key in to_delete: + del vc.serialized_args[key] + return m_ns + + +def _update_m_ns(vc, m_ns): + instance = vc.instance + for key, ids in m_ns.items(): + child_rel = getattr(vc.instance, "_m_n_table_{}".format(key)) + child_table = getattr(webapp_models, child_rel) + children = db.session.query(child_table).filter(child_table.id.in_(ids)).all() + setattr(instance, key, children) + + def default_create_func(vc): + m_ns = _filter_m_n(vc) instance = vc.model_view.model(**vc.serialized_args) - db.session.add(instance) + vc.instance = instance vc.instances = [instance] + _update_m_ns(vc, m_ns) + db.session.add(instance) def default_update_func(vc): + m_ns = _filter_m_n(vc) instance = vc.instances[0] + vc.instance = instance for k, v in vc.serialized_args.items(): setattr(instance, k, v) + _update_m_ns(vc, m_ns) db.session.add(instance) @@ -85,7 +119,7 @@ def default_render_func(vc): vc.template_ctx['instances'] = vc.instances vc.template_ctx['model_view'] = vc.model_view vc.template_ctx['model_views'] = MODEL_VIEWS - return render_template(vc.template, **vc.template_ctx) + return render_template(vc.template, **vc.template_ctx) def default_commit_func(vc): diff --git a/vm_gen/templates/_relationship_py b/vm_gen/templates/_relationship_py index 6af0c44..8dac0ae 100644 --- a/vm_gen/templates/_relationship_py +++ b/vm_gen/templates/_relationship_py @@ -1,9 +1,13 @@ - [%- if not column.secondary %] + [%- if not column.multiple %] [[ column.name ]]_id = db.Column(db.Integer, db.ForeignKey('[%- if column.to %][[ column.to|camel_to_snake ]][%- else %][[ column.name ]][% endif %].id')) [%- endif %] - [[ column.name|pluralize if column.secondary else column.name ]] = db.relationship('[%- if column.to %][[ column.to ]][%- else %][[ column.name|snake_to_camel ]][% endif %]', - [%- if column.secondary %]secondary=[[ column.secondary ]], [%- endif %] + [[ column.name|pluralize if column.multiple else column.name ]] = db.relationship('[%- if column.to %][[ column.to ]][%- else %][[ column.name|snake_to_camel ]][% endif %]', + [%- if column.multiple %]secondary=[[ column.secondary.name ]], [%- endif %] backref=db.backref("[%- if column.backref %][[ column.backref ]][%- else %][[ name|camel_to_snake|pluralize ]][%- endif %]"), [%- if column.foreign_keys %]foreign_keys=[ [[ column.foreign_keys ]]_id],[%- endif %] - ) \ No newline at end of file + ) + [%- if column.multiple %] + + _m_n_table_[[ column.name|pluralize ]] = '[%- if column.to %][[ column.to ]][%- else %][[ column.name|snake_to_camel ]][% endif %]' + [%- endif %] \ No newline at end of file diff --git a/vm_gen/templates/html/_create.html b/vm_gen/templates/html/_create.html index c3211f9..856b2f3 100644 --- a/vm_gen/templates/html/_create.html +++ b/vm_gen/templates/html/_create.html @@ -3,13 +3,22 @@ [%- for column in columns %] : [%- if column.type in ['relationship'] %] - + [%- if not column.secondary %] + [%- endif %] {%- for sub_instance in model_views.[[ column.name ]].model.query.all() %} {%- endfor %} + [%- elif column.type in ['choice', ] %] + [%- elif column.type in ['number', 'int', 'integer', ] %] [%- 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 69a3d81..ab8a0b3 100644 --- a/vm_gen/templates/html/_get.html +++ b/vm_gen/templates/html/_get.html @@ -6,7 +6,11 @@ [%- elif column.type in ['relationship'] %] -
  • [[ column.name ]]: {{ instance.[[ column.name ]] }}
  • + [%- if column.multiple %] +
  • [[ column.name|pluralize ]]: {{ instance.[[ column.name|pluralize ]] }}
  • + [%- else %] +
  • [[ column.name ]]: {{ instance.[[ column.name ]] }}
  • + [%- endif %] [%- else %]
  • [[ column.name ]]: {{ instance.[[ column.name ]] }}
  • [%- endif %] diff --git a/vm_gen/templates/html/_table.html b/vm_gen/templates/html/_table.html index 1a50389..d9ec31b 100644 --- a/vm_gen/templates/html/_table.html +++ b/vm_gen/templates/html/_table.html @@ -14,7 +14,17 @@ [%- for column in columns %] {% if "[[ column.name ]]" not in skip_columns %} - {{ instance.[[ column.name ]] }} + + [%- if column.type in ['relationship'] %] + [%- if column.multiple %] + {{ instance.[[ column.name|pluralize ]] }} + [%- else %] + {{ instance.[[ column.name ]] }} + [%- endif %] + [%- else %] + {{ instance.[[ column.name ]] }} + [%- endif %] + {% endif %} [%- endfor %] diff --git a/vm_gen/templates/html/_update.html b/vm_gen/templates/html/_update.html index baa5be4..b2d9794 100644 --- a/vm_gen/templates/html/_update.html +++ b/vm_gen/templates/html/_update.html @@ -4,12 +4,23 @@ : [%- if column.type in ['relationship'] %] + [%- elif column.type in ['choice', ] %] + [%- elif column.type in ['number', 'int', 'integer', ] %] [%- endif %] +
    [%- endfor %] \ No newline at end of file diff --git a/vm_gen/vm_gen.py b/vm_gen/vm_gen.py index 5ddb822..082ca4a 100644 --- a/vm_gen/vm_gen.py +++ b/vm_gen/vm_gen.py @@ -24,14 +24,15 @@ def _process_choice(column): } -def process_secondary(secondary): - col1, col2 = secondary.split('_') +def process_secondary(view_model, column_name): + model_name = camel_case_to_snake_case(view_model.get('name')) + secondary = "{}__{}".format(model_name, column_name) return { 'name': secondary, 'columns': [{ - 'name': col1 + 'name': model_name }, { - 'name': col2 + 'name': column_name }] } @@ -49,11 +50,12 @@ def enrich_view_model(view_model): _column_type = 'db.Boolean' elif column_type in ['relationship', ]: _column_type = 'relationship' - secondary = column.get('secondary') - if secondary: + multiple = column.get('multiple') + if multiple: if '_secondaries' not in view_model: view_model['_secondaries'] = [] - secondary_model = process_secondary(secondary) + secondary_model = process_secondary(view_model, column_name) + column.update({'secondary': secondary_model}) view_model['_secondaries'].append(secondary_model) elif column_type in ['choice', ]: if '_choice_types' not in view_model: