Menu
CoddyTech

Her Kaynak için Bir Sınıf

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

task_detail artık bir dizi if request.method == ... bloğundan ve bunlarla uyumlu tutulması gereken bir yöntem listesinden oluşuyor. Kullandığın her genel görünümün temel sınıfı olan Django'nun View sınıfı, bu kayıt işini halleder.

Sınıfa, her HTTP yöntemi için küçük harfle adlandırılmış bir yöntem ekle. View, isteğin adını taşıyan yöntemi çağırır ve diğer tüm yöntemler için 405 yanıtı verir. URL'deki değerler, işlev görünümünde olduğu gibi request'ten sonra gelir ve rota .as_view() kullanır. Bir ziyaretçinin renk teması bir kaynak olarak:

@method_decorator(csrf_exempt, name="dispatch")
class Theme(View):
    def get(self, request):
        return JsonResponse({"theme": request.session.get("theme", "light")})

    def put(self, request):
        data = json.loads(request.body)
        request.session["theme"] = data["theme"]
        return JsonResponse({"theme": data["theme"]})

@csrf_exempt işlevlerde çalışır. Bir sınıfta method_decorator bunu, her isteğin içinden geçtiği yöntem olan dispatch üzerine uygular.

challenge icon

Görev

Orta

task_detail öğesini TaskDetail(View) sınıfına dönüştür:

  • Her biri işlevin yaptığı işi yapan, 404 yanıtı da dâhil get, patch ve delete yöntemleri.
  • method_decorator ile CSRF koruması dışında bırak.
  • Rota, adı yine task_detail olan views.TaskDetail.as_view() öğesini kullanır.

Run'a bas, ardından /api/tasks/1/ adresini aç: görev daha önce olduğu gibi görünür.

Kendin dene

import json

from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_GET, require_http_methods

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()})


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


@csrf_exempt
@require_http_methods(["GET", "POST"])
def task_list(request):
    if request.method == "POST":
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({"error": "The body is not valid JSON."}, status=400)
        errors = {}
        title = data.get("title", "").strip()
        if not title:
            errors["title"] = "This field is required."
        if errors:
            return JsonResponse({"errors": errors}, status=400)
        task = Task.objects.create(
            title=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)


@csrf_exempt
@require_http_methods(["GET", "PATCH", "DELETE"])
def task_detail(request, pk):
    task = Task.objects.filter(pk=pk).first()
    if task is None:
        return JsonResponse({"error": "Task not found"}, status=404)
    if request.method == "DELETE":
        task.delete()
        return HttpResponse(status=204)
    if request.method == "PATCH":
        data = json.loads(request.body)
        if "title" in data:
            task.title = data["title"]
        if "done" in data:
            task.done = data["done"]
        task.save()
    return JsonResponse(task_to_dict(task))
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

JSON API'leri bölümündeki tüm dersler

Kendi başına pratik yap: Django playground