m_n create/update works UNLESS update is none
This commit is contained in:
parent
a567739eaf
commit
4ef7da556c
@ -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 {
|
||||
|
@ -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):
|
||||
|
@ -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 %]
|
||||
)
|
||||
)
|
||||
[%- if column.multiple %]
|
||||
|
||||
_m_n_table_[[ column.name|pluralize ]] = '[%- if column.to %][[ column.to ]][%- else %][[ column.name|snake_to_camel ]][% endif %]'
|
||||
[%- endif %]
|
@ -3,13 +3,22 @@
|
||||
[%- for column in columns %]
|
||||
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
|
||||
[%- if column.type in ['relationship'] %]
|
||||
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]" [%- if column.secondary %]multiple[%- endif %]
|
||||
name="[[ column.name ]]_id">
|
||||
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]" [%- if column.multiple %]multiple
|
||||
name="_m_n_[[ column.name|pluralize ]]"[% else %]name="[[ column.name ]]_id"[%- endif %]>
|
||||
[%- if not column.secondary %]
|
||||
<option selected="selected">Choose...</option>
|
||||
[%- endif %]
|
||||
{%- for sub_instance in model_views.[[ column.name ]].model.query.all() %}
|
||||
<option value="{{ sub_instance.id }}" {% if instance and instance.id == sub_instance.id %}selected="selected"{% endif %}>{{ sub_instance.name }}</option>
|
||||
{%- endfor %}
|
||||
</select>
|
||||
[%- elif column.type in ['choice', ] %]
|
||||
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||
name="[[ column.name ]]_id">
|
||||
[%- for value, display in column.choices.items() %]
|
||||
<option value="[[ value ]]" {% if instance and instance.[[ column.name ]] == "[[ value ]]" %}selected="selected"{% endif %}>[[ display ]]</option>
|
||||
[%- endfor %]
|
||||
</select>
|
||||
[%- elif column.type in ['number', 'int', 'integer', ] %]
|
||||
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||
type="number" name="[[ column.name ]]"
|
||||
@ -19,6 +28,7 @@
|
||||
type="text" name="[[ column.name ]]" autocomplete="off"
|
||||
/>
|
||||
[%- endif %]
|
||||
<br>
|
||||
[%- endfor %]
|
||||
<input type="submit">
|
||||
</form>
|
@ -6,7 +6,11 @@
|
||||
<source src="{{ url_for('oshipka_bp.get_media', filepath=instance.[[ column.name ]]) }}" type="video/webm">
|
||||
</video>
|
||||
[%- elif column.type in ['relationship'] %]
|
||||
<li id="display-[[ name|camel_to_snake ]]-[[ column.name ]]"><strong>[[ column.name ]]</strong>: {{ instance.[[ column.name ]] }}</li>
|
||||
[%- if column.multiple %]
|
||||
<li id="display-[[ name|camel_to_snake ]]-[[ column.name|pluralize ]]"><strong>[[ column.name|pluralize ]]</strong>: {{ instance.[[ column.name|pluralize ]] }}</li>
|
||||
[%- else %]
|
||||
<li id="display-[[ name|camel_to_snake ]]-[[ column.name ]]"><strong>[[ column.name ]]</strong>: {{ instance.[[ column.name ]] }}</li>
|
||||
[%- endif %]
|
||||
[%- else %]
|
||||
<li id="display-[[ name|camel_to_snake ]]-[[ column.name ]]"><strong>[[ column.name ]]</strong>: {{ instance.[[ column.name ]] }}</li>
|
||||
[%- endif %]
|
||||
|
@ -14,7 +14,17 @@
|
||||
<tr>
|
||||
[%- for column in columns %]
|
||||
{% if "[[ column.name ]]" not in skip_columns %}
|
||||
<td>{{ instance.[[ column.name ]] }}</td>
|
||||
<td>
|
||||
[%- if column.type in ['relationship'] %]
|
||||
[%- if column.multiple %]
|
||||
{{ instance.[[ column.name|pluralize ]] }}
|
||||
[%- else %]
|
||||
{{ instance.[[ column.name ]] }}
|
||||
[%- endif %]
|
||||
[%- else %]
|
||||
{{ instance.[[ column.name ]] }}
|
||||
[%- endif %]
|
||||
</td>
|
||||
{% endif %}
|
||||
[%- endfor %]
|
||||
<td>
|
||||
|
@ -4,12 +4,23 @@
|
||||
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
|
||||
[%- if column.type in ['relationship'] %]
|
||||
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||
name="[[ column.name ]]_id">
|
||||
[%- if column.multiple %]multiple name="_m_n_[[ column.name|pluralize ]]"[% else %]name="[[ column.name ]]_id"[%- endif %]>
|
||||
{%- for sub_instance in model_views.[[ column.name ]].model.query.all() %}
|
||||
<option value="{{ sub_instance.id }}"
|
||||
[%- if column.multiple %]
|
||||
{% if sub_instance in instance.[[ column.name|pluralize ]] %}selected="selected"{% endif %}>{{ sub_instance.name }}</option>
|
||||
[%- else %]
|
||||
{% if instance.[[ column.name ]]_id == sub_instance.id %}selected="selected"{% endif %}>{{ sub_instance.name }}</option>
|
||||
[%- endif %]
|
||||
{%- endfor %}
|
||||
</select>
|
||||
[%- elif column.type in ['choice', ] %]
|
||||
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||
name="[[ column.name ]]_id">
|
||||
[%- for value, display in column.choices.items() %]
|
||||
<option value="[[ value ]]" {% if instance.[[ column.name ]] == "[[ value ]]" %}selected="selected"{% endif %}>[[ display ]]</option>
|
||||
[%- endfor %]
|
||||
</select>
|
||||
[%- elif column.type in ['number', 'int', 'integer', ] %]
|
||||
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||
value="{{ instance.[[ column.name ]] }}"
|
||||
@ -21,6 +32,7 @@
|
||||
type="text" name="[[ column.name ]]" autocomplete="off"
|
||||
/>
|
||||
[%- endif %]
|
||||
<br>
|
||||
[%- endfor %]
|
||||
<input type="submit">
|
||||
</form>
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user