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-family: Open Sans, Arial sans-serif;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=number] {
|
||||||
|
min-width: 70px;
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
min-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.full-width {
|
.full-width {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import importlib
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
import inflect
|
import inflect
|
||||||
@ -6,15 +7,21 @@ from flask import flash, render_template, redirect, request, url_for, jsonify
|
|||||||
from oshipka.persistance import db
|
from oshipka.persistance import db
|
||||||
from oshipka.util.strings import camel_case_to_snake_case
|
from oshipka.util.strings import camel_case_to_snake_case
|
||||||
|
|
||||||
|
webapp_models = importlib.import_module("webapp.models")
|
||||||
|
|
||||||
MODEL_VIEWS = dict()
|
MODEL_VIEWS = dict()
|
||||||
|
|
||||||
|
|
||||||
def default_get_args_func(view_context):
|
def default_get_args_func(view_context):
|
||||||
view_context.serialized_args = request.args
|
view_context.serialized_args = request.args
|
||||||
|
|
||||||
|
|
||||||
def default_get_form_func(vc):
|
def default_get_form_func(vc):
|
||||||
vc.redirect_next = request.form.get('_next')
|
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 = []
|
to_delete = []
|
||||||
for key, value in vc.serialized_args.items():
|
for key, value in vc.serialized_args.items():
|
||||||
if key.endswith('_id'):
|
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()
|
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):
|
def default_create_func(vc):
|
||||||
|
m_ns = _filter_m_n(vc)
|
||||||
instance = vc.model_view.model(**vc.serialized_args)
|
instance = vc.model_view.model(**vc.serialized_args)
|
||||||
db.session.add(instance)
|
vc.instance = instance
|
||||||
vc.instances = [instance]
|
vc.instances = [instance]
|
||||||
|
_update_m_ns(vc, m_ns)
|
||||||
|
db.session.add(instance)
|
||||||
|
|
||||||
|
|
||||||
def default_update_func(vc):
|
def default_update_func(vc):
|
||||||
|
m_ns = _filter_m_n(vc)
|
||||||
instance = vc.instances[0]
|
instance = vc.instances[0]
|
||||||
|
vc.instance = instance
|
||||||
for k, v in vc.serialized_args.items():
|
for k, v in vc.serialized_args.items():
|
||||||
setattr(instance, k, v)
|
setattr(instance, k, v)
|
||||||
|
_update_m_ns(vc, m_ns)
|
||||||
db.session.add(instance)
|
db.session.add(instance)
|
||||||
|
|
||||||
|
|
||||||
@ -85,7 +119,7 @@ def default_render_func(vc):
|
|||||||
vc.template_ctx['instances'] = vc.instances
|
vc.template_ctx['instances'] = vc.instances
|
||||||
vc.template_ctx['model_view'] = vc.model_view
|
vc.template_ctx['model_view'] = vc.model_view
|
||||||
vc.template_ctx['model_views'] = MODEL_VIEWS
|
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):
|
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'))
|
[[ column.name ]]_id = db.Column(db.Integer, db.ForeignKey('[%- if column.to %][[ column.to|camel_to_snake ]][%- else %][[ column.name ]][% endif %].id'))
|
||||||
[%- endif %]
|
[%- endif %]
|
||||||
[[ column.name|pluralize if column.secondary else column.name ]] = db.relationship('[%- if column.to %][[ column.to ]][%- else %][[ column.name|snake_to_camel ]][% 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.secondary %]secondary=[[ column.secondary ]], [%- endif %]
|
[%- if column.multiple %]secondary=[[ column.secondary.name ]], [%- endif %]
|
||||||
backref=db.backref("[%- if column.backref %][[ column.backref ]][%- else %][[ name|camel_to_snake|pluralize ]][%- 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.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 %]
|
[%- for column in columns %]
|
||||||
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
|
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
|
||||||
[%- if column.type in ['relationship'] %]
|
[%- if column.type in ['relationship'] %]
|
||||||
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]" [%- if column.secondary %]multiple[%- endif %]
|
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]" [%- if column.multiple %]multiple
|
||||||
name="[[ column.name ]]_id">
|
name="_m_n_[[ column.name|pluralize ]]"[% else %]name="[[ column.name ]]_id"[%- endif %]>
|
||||||
|
[%- if not column.secondary %]
|
||||||
<option selected="selected">Choose...</option>
|
<option selected="selected">Choose...</option>
|
||||||
|
[%- endif %]
|
||||||
{%- for sub_instance in model_views.[[ column.name ]].model.query.all() %}
|
{%- 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>
|
<option value="{{ sub_instance.id }}" {% if instance and instance.id == sub_instance.id %}selected="selected"{% endif %}>{{ sub_instance.name }}</option>
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</select>
|
</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', ] %]
|
[%- elif column.type in ['number', 'int', 'integer', ] %]
|
||||||
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||||
type="number" name="[[ column.name ]]"
|
type="number" name="[[ column.name ]]"
|
||||||
@ -19,6 +28,7 @@
|
|||||||
type="text" name="[[ column.name ]]" autocomplete="off"
|
type="text" name="[[ column.name ]]" autocomplete="off"
|
||||||
/>
|
/>
|
||||||
[%- endif %]
|
[%- endif %]
|
||||||
|
<br>
|
||||||
[%- endfor %]
|
[%- endfor %]
|
||||||
<input type="submit">
|
<input type="submit">
|
||||||
</form>
|
</form>
|
@ -6,7 +6,11 @@
|
|||||||
<source src="{{ url_for('oshipka_bp.get_media', filepath=instance.[[ column.name ]]) }}" type="video/webm">
|
<source src="{{ url_for('oshipka_bp.get_media', filepath=instance.[[ column.name ]]) }}" type="video/webm">
|
||||||
</video>
|
</video>
|
||||||
[%- elif column.type in ['relationship'] %]
|
[%- 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 %]
|
[%- else %]
|
||||||
<li id="display-[[ name|camel_to_snake ]]-[[ column.name ]]"><strong>[[ column.name ]]</strong>: {{ instance.[[ column.name ]] }}</li>
|
<li id="display-[[ name|camel_to_snake ]]-[[ column.name ]]"><strong>[[ column.name ]]</strong>: {{ instance.[[ column.name ]] }}</li>
|
||||||
[%- endif %]
|
[%- endif %]
|
||||||
|
@ -14,7 +14,17 @@
|
|||||||
<tr>
|
<tr>
|
||||||
[%- for column in columns %]
|
[%- for column in columns %]
|
||||||
{% if "[[ column.name ]]" not in skip_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 %}
|
{% endif %}
|
||||||
[%- endfor %]
|
[%- endfor %]
|
||||||
<td>
|
<td>
|
||||||
|
@ -4,12 +4,23 @@
|
|||||||
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
|
<label for="input-[[ name|camel_to_snake ]]-[[ column.name ]]">[[ column.name ]]</label>:
|
||||||
[%- if column.type in ['relationship'] %]
|
[%- if column.type in ['relationship'] %]
|
||||||
<select id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
<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() %}
|
{%- for sub_instance in model_views.[[ column.name ]].model.query.all() %}
|
||||||
<option value="{{ sub_instance.id }}"
|
<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>
|
{% if instance.[[ column.name ]]_id == sub_instance.id %}selected="selected"{% endif %}>{{ sub_instance.name }}</option>
|
||||||
|
[%- endif %]
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</select>
|
</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', ] %]
|
[%- elif column.type in ['number', 'int', 'integer', ] %]
|
||||||
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
<input id="input-[[ name|camel_to_snake ]]-[[ column.name ]]"
|
||||||
value="{{ instance.[[ column.name ]] }}"
|
value="{{ instance.[[ column.name ]] }}"
|
||||||
@ -21,6 +32,7 @@
|
|||||||
type="text" name="[[ column.name ]]" autocomplete="off"
|
type="text" name="[[ column.name ]]" autocomplete="off"
|
||||||
/>
|
/>
|
||||||
[%- endif %]
|
[%- endif %]
|
||||||
|
<br>
|
||||||
[%- endfor %]
|
[%- endfor %]
|
||||||
<input type="submit">
|
<input type="submit">
|
||||||
</form>
|
</form>
|
@ -24,14 +24,15 @@ def _process_choice(column):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def process_secondary(secondary):
|
def process_secondary(view_model, column_name):
|
||||||
col1, col2 = secondary.split('_')
|
model_name = camel_case_to_snake_case(view_model.get('name'))
|
||||||
|
secondary = "{}__{}".format(model_name, column_name)
|
||||||
return {
|
return {
|
||||||
'name': secondary,
|
'name': secondary,
|
||||||
'columns': [{
|
'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'
|
_column_type = 'db.Boolean'
|
||||||
elif column_type in ['relationship', ]:
|
elif column_type in ['relationship', ]:
|
||||||
_column_type = 'relationship'
|
_column_type = 'relationship'
|
||||||
secondary = column.get('secondary')
|
multiple = column.get('multiple')
|
||||||
if secondary:
|
if multiple:
|
||||||
if '_secondaries' not in view_model:
|
if '_secondaries' not in view_model:
|
||||||
view_model['_secondaries'] = []
|
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)
|
view_model['_secondaries'].append(secondary_model)
|
||||||
elif column_type in ['choice', ]:
|
elif column_type in ['choice', ]:
|
||||||
if '_choice_types' not in view_model:
|
if '_choice_types' not in view_model:
|
||||||
|
Loading…
Reference in New Issue
Block a user