Adding some default CRUD behaviors.

This commit is contained in:
Yaro Kasear 2025-08-13 10:53:22 -05:00
parent c8190be21c
commit b2231f8ef9
6 changed files with 243 additions and 90 deletions

56
inventory/ui/blueprint.py Normal file
View file

@ -0,0 +1,56 @@
from flask import Blueprint, request, render_template, jsonify, abort
from sqlalchemy.exc import IntegrityError
from .defaults import (
default_query, default_create, default_update, default_delete, default_serialize
)
from .. import db
bp = Blueprint("ui", __name__, url_prefix="/ui")
def _normalize(s: str) -> str:
return s.replace("_", "").replace("-", "").lower()
def get_model_class(model_name: str):
"""Resolve a model class by name across SA/Flask-SA versions."""
target = _normalize(model_name)
# SA 2.x / Flask-SQLAlchemy 3.x path
registry = getattr(db.Model, "registry", None)
if registry and getattr(registry, "mappers", None):
for mapper in registry.mappers:
cls = mapper.class_
# match on class name w/ and w/o underscores
if _normalize(cls.__name__) == target or cls.__name__.lower() == model_name.lower():
return cls
# Legacy Flask-SQLAlchemy 2.x path (if someone runs old stack)
decl = getattr(db.Model, "_decl_class_registry", None)
if decl:
for cls in decl.values():
if isinstance(cls, type) and (
_normalize(cls.__name__) == target or cls.__name__.lower() == model_name.lower()
):
return cls
abort(404, f"Unknown resource '{model_name}'")
def call(Model, name, *args, **kwargs):
fn = getattr(Model, name, None)
return fn(*args, **kwargs) if callable(fn) else None
@bp.get("/<model_name>/list")
def list_items(model_name):
Model = get_model_class(model_name)
text = (request.args.get("q") or "").strip() or None
limit = min(int(request.args.get("limit", 100)), 500)
offset = int(request.args.get("offset", 0))
view = (request.args.get("view") or "option").strip()
rows = call(Model, "ui_query", db.session, text=text, limit=limit, offset=offset) \
or default_query(db.session, Model, text=text, limit=limit, offset=offset)
data = [ (call(Model, "ui_serialize", r, view=view) or default_serialize(Model, r, view=view))
for r in rows ]
return jsonify({"items": data})