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})
Вернуться на верх