diff --git a/crudkit/ui/fragments.py b/crudkit/ui/fragments.py index 9ac9166..ec1bd0c 100644 --- a/crudkit/ui/fragments.py +++ b/crudkit/ui/fragments.py @@ -1,26 +1,64 @@ from jinja2 import Environment, FileSystemLoader +from sqlalchemy.orm import class_mapper, RelationshipProperty import os FRAGMENT_PATH = os.path.join(os.path.dirname(__file__), 'templates') env = Environment(loader=FileSystemLoader(FRAGMENT_PATH)) -def render_field(field_name, value): +def render_field(field, value): + print(field) template = env.get_template('field.html') - return template.render(field_name=field_name, value=value) + return template.render( + field_name=field['name'], + field_label=field.get('label', field['name']), + value=value, + field_type=field.get('type', 'text'), + options=field.get('options', None) + ) + def render_table(objects): template = env.get_template('table.html') return template.render(objects=objects) -def render_form(model_cls, values): +def render_form(model_cls, values, session=None): template = env.get_template('form.html') fields = [] + fk_fields = set() + + mapper = class_mapper(model_cls) + for prop in mapper.iterate_properties: + # FK Relationship fields (many-to-one) + if isinstance(prop, RelationshipProperty) and prop.direction.name == 'MANYTOONE': + if session is None: + continue + + related_model = prop.mapper.class_ + options = session.query(related_model).all() + fields.append({ + 'name': f"{prop.key}_id", + 'label': prop.key, + 'type': 'select', + 'options': [ + {'value': getattr(obj, 'id'), 'label': str(obj)} + for obj in options + ] + }) + fk_fields.add(f"{prop.key}_id") + + # Now add basic columns — excluding FKs already covered for col in model_cls.__table__.columns: - if col.name == 'id': + if col.name in fk_fields: + continue + if col.name in ('id', 'created_at', 'updated_at'): continue if col.default or col.server_default or col.onupdate: continue - if col.name in ('created_at', 'updated_at'): - continue - fields.append(col) + fields.append({ + 'name': col.name, + 'label': col.name, + 'type': 'text', + }) + return template.render(fields=fields, values=values, render_field=render_field) + diff --git a/crudkit/ui/templates/field.html b/crudkit/ui/templates/field.html index d6904dc..28fcf7e 100644 --- a/crudkit/ui/templates/field.html +++ b/crudkit/ui/templates/field.html @@ -1,2 +1,16 @@ - - \ No newline at end of file + + +{% if field_type == 'select' %} + +{% else %} + +{% endif %} diff --git a/crudkit/ui/templates/form.html b/crudkit/ui/templates/form.html index 09ad44c..6109e25 100644 --- a/crudkit/ui/templates/form.html +++ b/crudkit/ui/templates/form.html @@ -1,6 +1,6 @@
diff --git a/test_app/app.py b/test_app/app.py index 8d3f8bd..9e0a837 100644 --- a/test_app/app.py +++ b/test_app/app.py @@ -24,7 +24,7 @@ def index(): devices = device_service.list() table = render_table(devices) - form = render_form(Device, {}) + form = render_form(Device, {}, session) return render_template('index.html', table=table, form=form) if __name__ == '__main__': diff --git a/test_app/templates/index.html b/test_app/templates/index.html index a690a2b..cf80ed9 100644 --- a/test_app/templates/index.html +++ b/test_app/templates/index.html @@ -7,7 +7,6 @@