Menu
CoddyTech

JSON Doğrulama Hataları

Coddy'nin Django Journey'sinin JSON API'leri bölümünün bir parçası. Ders 7 / 19.

Şu anda, başlıksız bir POST isteği KeyError hatasıyla çöker ve Django 500 Server Error yanıtı verir; bu da programa neyin düzeltilmesi gerektiği hakkında hiçbir şey söylemez.

Sorun veride olduğunda 400 Bad Request yanıtı ver ve neyin yanlış olduğunu JSON biçiminde, Django formunun hatalarını tuttuğu gibi her alan için bir mesajla belirt. Bir kitapçının kitabın yılını denetlemesi:

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)

İki tuzak daha var. Yalnızca boşluklardan oluşan bir başlık boş değildir, ancak " ".strip() değeri "" olur. JSON olmayan bir gövde ise json.loads işleminin json.JSONDecodeError hatası vermesine neden olur; try ve except bu hatayı 400 yanıtına dönüştürür. 4xx durum kodu, isteği gönderenin yanlış bir şey gönderdiği anlamına gelir; 5xx ise kodunun bozulduğu anlamına gelir.

challenge icon

Görev

Orta

POST /api/tasks/ hatalı veriler için 400 yanıtı versin:

  • Başlık yoksa veya yalnızca boşluklardan oluşuyorsa: {"errors": {"title": "This field is required."}} ve hiçbir şey kaydedilmez.
  • İstek gövdesi JSON değilse: {"error": "The body is not valid JSON."}.
  • Geçerli bir başlık, etrafındaki boşluklar kaldırılarak kaydedilir.

Run'a basın, ardından Shell sekmesinde: from django.test import Client; print(Client().post("/api/tasks/", {"title": " "}, content_type="application/json").json())

Kendin dene

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'leri bölümündeki tüm dersler

Kendi başına pratik yap: Django playground