Menu
CoddyTech

JSON 유효성 검사 오류

Coddy Django 여정의 JSON API 섹션에 포함된 레슨. 19개 중 7번째.

현재 제목이 없는 POST는 KeyError로 충돌하고, Django는 500 서버 오류로 응답합니다. 이 응답은 프로그램에 무엇을 고쳐야 하는지 전혀 알려 주지 않습니다.

문제가 데이터에 있을 때는 400 잘못된 요청으로 응답하고, Django 폼이 오류를 보관하는 방식처럼 JSON으로 무엇이 잘못되었는지 필드마다 메시지 하나씩 알려 주세요. 책방에서 책의 연도를 확인하는 경우를 살펴보겠습니다.

errors = {}
year = data.get("year")
if not isinstance(year, int) or year < 0:
    errors["year"] = "Enter the year as a whole number."
if errors:
    return JsonResponse({"errors": errors}, status=400)

두 가지 함정이 더 있습니다. 공백만 있는 제목은 비어 있지는 않지만, " ".strip()은 ""입니다. 그리고 JSON이 아닌 본문은 json.loads에서 json.JSONDecodeError를 발생시키며, 이를 try와 except로 처리하면 400 응답으로 바뀝니다. 4xx 상태 코드는 호출자가 잘못된 내용을 보냈다는 뜻이고, 5xx는 코드에 문제가 생겼다는 뜻입니다.

challenge icon

챌린지

중급

잘못된 데이터에 대해 POST /api/tasks/가 400을 반환하도록 하세요:

  • 제목이 없거나 공백만 있는 경우: {"errors": {"title": "This field is required."}}를 반환하고 아무것도 저장하지 않습니다.
  • 본문이 JSON이 아닌 경우: {"error": "The body is not valid JSON."}를 반환합니다.
  • 유효한 제목은 앞뒤 공백을 제거한 상태로 저장됩니다.

실행을 누른 다음 Shell 탭에서 다음을 실행하세요: from django.test import Client; print(Client().post("/api/tasks/", {"title": " "}, content_type="application/json").json())

직접 해보기

import json

from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt

from .models import Task


def task_to_dict(task):
    return {
        "id": task.id,
        "title": task.title,
        "done": task.done,
        "priority": task.priority,
    }


def home(request):
    return render(request, "tasks/home.html", {"tasks": Task.objects.all()})


def stats(request):
    data = {
        "total": Task.objects.count(),
        "done": Task.objects.filter(done=True).count(),
    }
    return JsonResponse(data)


@csrf_exempt
def task_list(request):
    if request.method == "POST":
        data = json.loads(request.body)
        task = Task.objects.create(
            title=data["title"],
            priority=data.get("priority", "normal"),
        )
        return JsonResponse(task_to_dict(task), status=201)
    tasks = Task.objects.all()
    done = request.GET.get("done")
    if done == "true":
        tasks = tasks.filter(done=True)
    elif done == "false":
        tasks = tasks.filter(done=False)
    return JsonResponse([task_to_dict(task) for task in tasks], safe=False)


def task_detail(request, pk):
    task = Task.objects.filter(pk=pk).first()
    if task is None:
        return JsonResponse({"error": "Task not found"}, status=404)
    return JsonResponse(task_to_dict(task))

JSON API의 모든 레슨

직접 연습해 보세요: Django 플레이그라운드