Adding some default CRUD behaviors.
This commit is contained in:
parent
c8190be21c
commit
b2231f8ef9
6 changed files with 243 additions and 90 deletions
56
inventory/ui/blueprint.py
Normal file
56
inventory/ui/blueprint.py
Normal 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})
|
||||
Loading…
Add table
Add a link
Reference in a new issue