No puedo averiguar si es posible pasar parámetros de consulta desde una página html estática a una vista para su procesamiento. Ahora he implementado la funcionalidad que necesito usando parámetros de ruta. Quiero hacer lo mismo, pero con parámetros de consulta.
principal.py
from helpers.utils import CustomURLProcessor app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") templates = Jinja2Templates(directory="templates") templates.env.globals['CustomURLProcessor'] = CustomURLProcessoreventos.py
router = APIRouter() templates = Jinja2Templates(directory="templates") @router.post('/invite/{event_invite}/sender/{sender}') async def decline_event_invite( request: Request, event_invite: int, sender: int, ): #logicrutas.py
api_router.include_router(events.router, prefix="/event")html
{{ url_for('decline_event_invite', event_invite=invite.id, sender=invite.sender) }} Funciona con "POST /event/invite/15/sender/3 HTTP/1.1" como muestra
Prueba con los parámetros de consulta
@router.post('/invite') async def decline_event_invite( request: Request, event_invite: Optional[str] = None, sender: Optional[str] = None, ): # logicY obten
raise NoMatchFound() starlette.routing.NoMatchFoundplantilla html sin ningún cambio
¿Puedo pasar parámetros de consulta de la plantilla a la lógica fastapi para procesar esta url /event/?event_invite=15&sender=3 ?
Este es un problema de Starlette (es decir, url_for() recibe parámetros de path , no parámetros de query ). Lo que podría hacer es crear un procesador de URL personalizado (como se muestra a continuación) y usarlo para pasar path y/o parámetros de query .
class CustomURLProcessor: def __init__(self): self.path = "" self.request = None def url_for(self, request: Request, name: str, **params: str): self.path = request.url_for(name, **params) self.request = request return self def include_query_params(self, **params: str): parsed = list(urllib.parse.urlparse(self.path)) parsed[4] = urllib.parse.urlencode(params) return urllib.parse.urlunparse(parsed) Recuerda agregar la clase CustomURLProcessor al entorno global de las plantillas:
templates.env.globals['CustomURLProcessor'] = CustomURLProcessorLuego, úselo en la plantilla Jinja, como se muestra a continuación:
{{ CustomURLProcessor().url_for(request, 'decline_event_invite').include_query_params(event_invite=invite.id, sender=invite.sender) }}Por favor, eche un vistazo a esta respuesta para ver un ejemplo de trabajo completo. Además, esta característica podría introducirse en la próxima versión de Starlette #1385 . Por lo tanto, es posible que desee vigilarlo.
Opciones alternativas para hacer que la clase CustomURLProcessor sea accesible desde las plantillas de Jinja, en caso de que templates.env.globals['CustomURLProcessor'] = CustomURLProcessor no funcione para usted, arrojando el siguiente error: jinja2.exceptions.UndefinedError: 'CustomURLProcessor' is undefined .
Opción 1
templates.env.globals.update(CustomURLProcessor=CustomURLProcessor)opcion 2
import helpers.utils templates.env.globals['CustomURLProcessor'] = helpers.utils.CustomURLProcessor # or, equivalently templates.env.globals.update(CustomURLProcessor=helpers.utils.CustomURLProcessor) Incluso podría agregar el módulo completo y usarlo en una plantilla Jinja como esta helpers.CustomURLProcessor().url_for(request... .
import helpers.utils templates.env.globals['helpers'] = helpers.utilsOpción 3
La última opción sería pasarlo como parte de su TemplateResponse .
return templates.TemplateResponse("index.html", {"request": request, "CustomURLProcessor": CustomURLProcessor})Si nada de lo anterior funcionó, tal vez otras opciones descritas aquí podrían ayudar, o el problema probablemente se encuentre en otra parte.