Coverage for src / lexigram / admin / relations / routes.py: 16%
50 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-13 22:14 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-13 22:14 +0800
1"""Route registration for relation managers."""
3from __future__ import annotations
5from typing import TYPE_CHECKING, Any
7from starlette.responses import HTMLResponse
8from starlette.routing import Route
10if TYPE_CHECKING:
11 from starlette.requests import Request
13 from lexigram.admin.relations.manager_ext import RelationManager
16def register_relation_routes(
17 resource_name: str,
18 manager_class: type[RelationManager],
19) -> list[Route]:
20 """Create Starlette Route objects for a relation manager."""
21 prefix = f"/{resource_name}"
23 async def _handle_list(request: Request) -> HTMLResponse:
24 parent_id = request.path_params.get("parent_id", "")
25 mgr = _create_manager(manager_class, parent_id)
26 html = await mgr.render(request, resource_name)
27 return HTMLResponse(html)
29 async def _handle_create_form(request: Request) -> HTMLResponse:
30 parent_id = request.path_params.get("parent_id", "")
31 mgr = _create_manager(manager_class, parent_id)
32 form = mgr.create_form()
33 return HTMLResponse(form or "<div>No create form available</div>")
35 async def _handle_create(request: Request) -> HTMLResponse:
36 parent_id = request.path_params.get("parent_id", "")
37 mgr = _create_manager(manager_class, parent_id)
38 await mgr.get_query()
39 html = await mgr.render(request, resource_name)
40 return HTMLResponse(html)
42 async def _handle_edit_form(request: Request) -> HTMLResponse:
43 parent_id = request.path_params.get("parent_id", "")
44 record_id = request.path_params.get("record_id", "")
45 mgr = _create_manager(manager_class, parent_id)
46 record = await _get_record(mgr, record_id)
47 form = mgr.edit_form(record) if record else None
48 return HTMLResponse(form or f"<div>Edit form for {record_id}</div>")
50 async def _handle_update(request: Request) -> HTMLResponse:
51 parent_id = request.path_params.get("parent_id", "")
52 record_id = request.path_params.get("record_id", "")
53 mgr = _create_manager(manager_class, parent_id)
54 html = await mgr.render(request, resource_name)
55 return HTMLResponse(html)
57 async def _handle_delete(request: Request) -> HTMLResponse:
58 parent_id = request.path_params.get("parent_id", "")
59 record_id = request.path_params.get("record_id", "")
60 mgr = _create_manager(manager_class, parent_id)
61 return HTMLResponse("")
63 return [
64 Route(
65 path=f"{prefix}/{{parent_id}}/relations/{{rel_name}}",
66 endpoint=_handle_list,
67 methods=["GET"],
68 ),
69 Route(
70 path=f"{prefix}/{{parent_id}}/relations/{{rel_name}}/new",
71 endpoint=_handle_create_form,
72 methods=["GET"],
73 ),
74 Route(
75 path=f"{prefix}/{{parent_id}}/relations/{{rel_name}}",
76 endpoint=_handle_create,
77 methods=["POST"],
78 ),
79 Route(
80 path=f"{prefix}/{{parent_id}}/relations/{{rel_name}}/{{record_id}}/edit",
81 endpoint=_handle_edit_form,
82 methods=["GET"],
83 ),
84 Route(
85 path=f"{prefix}/{{parent_id}}/relations/{{rel_name}}/{{record_id}}",
86 endpoint=_handle_update,
87 methods=["PUT"],
88 ),
89 Route(
90 path=f"{prefix}/{{parent_id}}/relations/{{rel_name}}/{{record_id}}",
91 endpoint=_handle_delete,
92 methods=["DELETE"],
93 ),
94 ]
97def _create_manager(
98 manager_class: type[RelationManager], parent_id: Any
99) -> RelationManager:
100 return manager_class(parent_id=parent_id)
103async def _get_record(mgr: RelationManager, record_id: str) -> Any:
104 items = await mgr.get_query()
105 for item in items:
106 if str(getattr(item, "id", "")) == record_id:
107 return item
108 return None
111__all__ = [
112 "register_relation_routes",
113]