fix(views): make Restaurant JSON-safe before passing to Jinja
All four CMS pages (menu / orders / kds / settings) crashed with
TypeError: JSONEncoder.default() missing 1 required positional
argument: 'o'
because templates do `{{ restaurant | tojson | safe }}`. `tojson`
runs Python's stdlib `json.JSONEncoder` which can't serialize the
`datetime` on `Restaurant.time` (or any other datetime nested in
the model). The browser saw '500 / 'o'' (KeyError-flavored).
Pydantic v1's .json() handles datetime correctly (ISO 8601). New
helper _restaurant_jsonable rounds-trips the Restaurant via .json()
+ json.loads() and returns a fully JSON-safe dict, then all four
view handlers pass that instead of restaurant.dict().
This commit is contained in:
parent
d4b1f4be53
commit
e98f82dced
1 changed files with 21 additions and 4 deletions
25
views.py
25
views.py
|
|
@ -15,6 +15,7 @@ Pages
|
||||||
All pages require a logged-in LNbits user (check_user_exists).
|
All pages require a logged-in LNbits user (check_user_exists).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, Request
|
from fastapi import APIRouter, Depends, Request
|
||||||
|
|
@ -26,6 +27,7 @@ from lnbits.decorators import check_user_exists
|
||||||
from lnbits.helpers import template_renderer
|
from lnbits.helpers import template_renderer
|
||||||
|
|
||||||
from .crud import get_restaurant_by_slug
|
from .crud import get_restaurant_by_slug
|
||||||
|
from .models import Restaurant
|
||||||
|
|
||||||
restaurant_generic_router = APIRouter()
|
restaurant_generic_router = APIRouter()
|
||||||
|
|
||||||
|
|
@ -34,6 +36,21 @@ def restaurant_renderer():
|
||||||
return template_renderer(["restaurant/templates"])
|
return template_renderer(["restaurant/templates"])
|
||||||
|
|
||||||
|
|
||||||
|
def _restaurant_jsonable(restaurant: Restaurant) -> dict:
|
||||||
|
"""
|
||||||
|
Convert a Restaurant pydantic model to a plain JSON-serializable
|
||||||
|
dict for Jinja's `tojson` filter.
|
||||||
|
|
||||||
|
`restaurant.dict()` returns a dict with a `datetime` on `time`,
|
||||||
|
which Python's stdlib `JSONEncoder` (used by Jinja `tojson`) can't
|
||||||
|
serialize — it errors out as
|
||||||
|
TypeError: JSONEncoder.default() missing 1 required positional argument: 'o'
|
||||||
|
Pydantic v1's `.json()` knows how to serialize datetime as
|
||||||
|
ISO-8601, so we round-trip via JSON to get a clean dict.
|
||||||
|
"""
|
||||||
|
return json.loads(restaurant.json())
|
||||||
|
|
||||||
|
|
||||||
@restaurant_generic_router.get("/", response_class=HTMLResponse)
|
@restaurant_generic_router.get("/", response_class=HTMLResponse)
|
||||||
async def index(request: Request, user: User = Depends(check_user_exists)):
|
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||||
return restaurant_renderer().TemplateResponse(
|
return restaurant_renderer().TemplateResponse(
|
||||||
|
|
@ -56,7 +73,7 @@ async def menu_builder(
|
||||||
{
|
{
|
||||||
"request": request,
|
"request": request,
|
||||||
"user": user.json(),
|
"user": user.json(),
|
||||||
"restaurant": restaurant.dict(),
|
"restaurant": _restaurant_jsonable(restaurant),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -75,7 +92,7 @@ async def orders(
|
||||||
{
|
{
|
||||||
"request": request,
|
"request": request,
|
||||||
"user": user.json(),
|
"user": user.json(),
|
||||||
"restaurant": restaurant.dict(),
|
"restaurant": _restaurant_jsonable(restaurant),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -94,7 +111,7 @@ async def kds(
|
||||||
{
|
{
|
||||||
"request": request,
|
"request": request,
|
||||||
"user": user.json(),
|
"user": user.json(),
|
||||||
"restaurant": restaurant.dict(),
|
"restaurant": _restaurant_jsonable(restaurant),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -113,6 +130,6 @@ async def settings_page(
|
||||||
{
|
{
|
||||||
"request": request,
|
"request": request,
|
||||||
"user": user.json(),
|
"user": user.json(),
|
||||||
"restaurant": restaurant.dict(),
|
"restaurant": _restaurant_jsonable(restaurant),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue