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 if request.method == ... blokları zincirinden ve bunlarla uyumlu tutulması gereken bir yöntemler listesinden oluşuyor. Kullandığın tüm genel görünümlerin temel sınıfı olan Django'nun View sınıfı bu takibi senin yerine yapar.

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 isteklere 405 yanıtı verir. URL'deki değerler, bir işlev görünümünde olduğu gibi request parametresinden sonra gelir ve rota .as_view() kullanır. Burada kaynak, oturumda tutulan bir ziyaretçinin renk temasıdır:

from django.utils.decorators import method_decorator
from django.views import View

@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şlevler üzerinde çalışır. Bir sınıfta ise method_decorator onu her isteğin içinden geçtiği dispatch yöntemine uygular.

challenge icon

Görev

Orta

task_detail'ı bir sınıfa dönüştür.

  1. tasks/views.py içinde, django.views modülünden View'ı ve django.utils.decorators modülünden method_decorator'ı içe aktar.
  2. Fonksiyonu ve her iki dekoratörü class TaskDetail(View) ile değiştir. Bu sınıfın get, patch ve delete metotları (self, request, pk) parametrelerini alır ve her biri eski dalının yaptığı işi yapar.
  3. dispatch üzerine method_decorator(csrf_exempt) ekleyerek sınıfı CSRF korumasından muaf tut.
  4. tasks/urls.py içinde, rotayı views.TaskDetail.as_view() öğesine yönlendir; adı yine task_detail olsun.

/api/tasks/1/ adresini aç: Buy milk, JSON olarak görüntülenir.

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