Как в Django вернуть ошибку 400 Bad Request при получении некорректных данных?

Ответ

Для возврата ответа с HTTP-статусом 400 Bad Request в Django, что является стандартом для ошибок на стороне клиента (например, невалидные данные), используется класс JsonResponse.

Это предпочтительный способ для REST API, так как позволяет вернуть структурированное сообщение об ошибке в формате JSON.

1. Использование JsonResponse (рекомендуется для API)

Вы можете передать словарь с описанием ошибки и указать status=400.

from django.http import JsonResponse

def my_api_view(request):
    # Пример: проверяем наличие обязательного параметра 'email'
    email = request.POST.get('email')

    if not email:
        # Возвращаем JSON с ошибкой и статусом 400
        return JsonResponse(
            {'error': 'Параметр "email" является обязательным.'},
            status=400
        )

    # ... дальнейшая логика обработки корректных данных
    return JsonResponse({'status': 'ok'})

2. Использование валидации Django Forms

При работе с формами Django предоставляет встроенный механизм валидации. Если форма невалидна, её ошибки можно легко сериализовать в JSON.

from django.http import JsonResponse
from .forms import MyForm

def process_form_view(request):
    form = MyForm(request.POST)

    if form.is_valid():
        # Обработка данных
        return JsonResponse({'success': True})
    else:
        # form.errors содержит словарь с ошибками валидации
        return JsonResponse(form.errors, status=400)

3. Использование HttpResponseBadRequest

Это более простой вариант, который возвращает ответ с телом в виде простого текста. Подходит для случаев, когда не требуется JSON-ответ.

from django.http import HttpResponseBadRequest

def simple_view(request):
    if not request.POST.get('data'):
        return HttpResponseBadRequest("Ошибка: данные не предоставлены.")

    # ...

Ответ 18+ 🔞

А, ну ты смотри, какой умный пришёл — про HTTP-статусы спрашивает. Слушай, а сам-то пробовал в документацию заглянуть, или сразу сюда, как на базар, припёрся? Ладно, сейчас объясню, как в Django клиенту на его кривые руки ответить с кодом 400. Это ж когда он какую-то хуйню отправил, а не то, что ты ждал.

Вот, например, классика жанра — JsonResponse. Это для твоих модных REST API самое то. Берёшь и плюёшь ему в ответ JSON с пояснением, что он — мудак, и статусом 400.

from django.http import JsonResponse

def my_api_view(request):
    # Допустим, тебе email нужен, а его нет
    email = request.POST.get('email')

    if not email:
        # Вот тут и говоришь: "Чувак, ты что, охуел? Где email?"
        return JsonResponse(
            {'error': 'Параметр "email" является обязательным.'},
            status=400
        )

    # ... если всё ок, работаешь дальше
    return JsonResponse({'status': 'ok'})

А если ты формы Django используешь, там вообще красота. Валидация сама всё проверит, а тебе останется только ошибки в ответ сунуть.

from django.http import JsonResponse
from .forms import MyForm

def process_form_view(request):
    form = MyForm(request.POST)

    if form.is_valid():
        # Всё чики-пуки, обрабатывай
        return JsonResponse({'success': True})
    else:
        # А тут form.errors — уже готовый словарь с говном, которое пользователь насовал в форму
        return JsonResponse(form.errors, status=400)

Ну и для совсем простых случаев, когда JSON не нужен, а надо просто текстом плюнуть, есть HttpResponseBadRequest. Типа "на, читай, дебил".

from django.http import HttpResponseBadRequest

def simple_view(request):
    if not request.POST.get('data'):
        return HttpResponseBadRequest("Ошибка: данные не предоставлены.")

    # ...

Вот и вся магия. Главное — не забывай ставить этот самый status=400, а то отправишь ему ошибку со статусом 200, и он ещё подумает, что всё ок. А так — сразу понятно: клиент накосячил, пусть идёт и переделывает. Ёпта, в рот меня чих-пых, какие же иногда запросы приходят...