I have encountered strange redirect behaviour after returning a RedirectResponse object
events.py
router = APIRouter()
@router.post('/create', response_model=EventBase)
async def event_create(
request: Request,
user_id: str = Depends(get_current_user),
service: EventsService = Depends(),
form: EventForm = Depends(EventForm.as_form)
):
event = await service.post(
...
)
redirect_url = request.url_for('get_event', **{'pk': event['id']})
return RedirectResponse(redirect_url)
@router.get('/{pk}', response_model=EventSingle)
async def get_event(
request: Request,
pk: int,
service: EventsService = Depends()
):
....some logic....
return templates.TemplateResponse(
'event.html',
context=
{
...
}
)
routers.py
api_router = APIRouter()
...
api_router.include_router(events.router, prefix="/event")
this code returns the result
127.0.0.1:37772 - "POST /event/22 HTTP/1.1" 405 Method Not Allowed
OK, I see that for some reason a POST request is called instead of a GET request. I search for an explanation and find that the RedirectResponse object defaults to code 307 and calls POST link
I follow the advice and add a status
redirect_url = request.url_for('get_event', **{'pk': event['id']}, status_code=status.HTTP_302_FOUND)
And get
starlette.routing.NoMatchFound
for the experiment, I'm changing @router.get('/{pk}', response_model=EventSingle)
to @router.post('/{pk}', response_model=EventSingle)
and the redirect completes successfully, but the post request doesn't suit me here. What am I doing wrong?
UPD
html form for running event/create logic
base.html
<form action="{{ url_for('event_create')}}" method="POST">
...
</form>
base_view.py
@router.get('/', response_class=HTMLResponse)
async def main_page(request: Request,
activity_service: ActivityService = Depends()):
activity = await activity_service.get()
return templates.TemplateResponse('base.html', context={'request': request,
'activities': activity})
status_code=status.HTTP_303_SEE_OTHER
same resultstarlette.routing.NoMatchFound
– Sharleensharlenestatus_code
tourl_for
instead of adding it to theRedirectResponse
, that's probably why you're getting theNoMatchFound
: it'strying to match a route with a parameterstatus_code
and not finding it. – Varini