Django: как сделать функцию get param или 404?
Я хочу, чтобы мои конечные точки выбрасывали код состояния 404 С сообщением типа "параметр foo не найден", если в запросе отсутствует обязательное поле. Поскольку у меня слишком много конечных точек, добавление 3 строк кода (try, except, return) не является для меня счастливым решением. Поэтому я хочу сделать функцию, подобную get_object_or_404 из django.shortcuts, где просто используя функцию, запрос возвращает 404 вместо того, чтобы просто вызвать исключение и обрушить сервер.
Посмотрев на функцию get_object_or_404, я заметил, что она делает raise Http404 и это действительно работает, но она всегда возвращает "detail": "Not Found", игнорируя любой параметр, который я передаю в код, вызывающий исключение.
Вот что я сделал:
class ParamNotFound(Exception):
def __init__(self, param_name):
self.param_name = param_name
self.status_code = 404
def __str__(self) -> str:
return f"Param {self.param_name} not found"
def get_body_param_or_404(params, param_name: str):
param = params.get(param_name, None)
if param is None:
raise ParamNotFound(f"param_name {param_name} not found")
return param
Но это вызывает исключение и приводит к краху сервера, если я не перехватываю его явно.
Есть ли чистый и короткий способ сделать это?
Что ж, ответ оказался сложнее, чем я думал. В итоге я реализовал промежуточное ПО, где я могу поймать собственное исключение, возвращающее пользовательский JsonResponse.
class ParamMiddleware:
def __init__(self, get_response) -> None:
self.get_response = get_response
def __call__(self, request):
return self.get_response(request)
def process_exception(self, request, exception):
if isinstance(exception, ParamNotFound):
return JsonResponse({"msg": str(exception), "status": 404})