Menu
CoddyTech

Projet : Les priorités

Fait partie de la section API JSON du Journey Django de Coddy. Leçon 15 sur 19.

Il est temps d’ajouter une fonctionnalité toi-même. Chaque tâche a une priority : low, normal ou high. L’API devrait permettre aux programmes de demander une priorité et empêcher quiconque d’en inventer une quatrième.

Tu as déjà tous les éléments : request.GET.get() pour un filtre, un QuerySet que tu peux filtrer plusieurs fois, et le dictionnaire errors qui renvoie une réponse 400.

Les valeurs autorisées se trouvent sur le modèle. Task.Priority est une classe TextChoices, et Task.Priority.values est la liste ["low", "normal", "high"]. La vérifier signifie qu’une priorité ajoutée ultérieurement au modèle sera acceptée sans qu’il soit nécessaire de modifier la vue.

challenge icon

Défi

Moyen

Ajoutez des priorités à l’API :

  • /api/tasks/?priority=high répertorie uniquement les tâches à priorité élevée et fonctionne avec ?done= : ?priority=high&done=false.
  • Une requête POST avec une priorité autre que low, normal ou high renvoie le code 400 avec une erreur sous "priority" et n’enregistre rien.
  • En l’absence de priorité, la valeur reste normal.

Appuyez sur Run : l’aperçu répertorie l’unique tâche à priorité élevée.

Essayez vous-même

import json

from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, render
from django.utils.decorators import method_decorator
from django.views import View
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")


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


def task_row(request, pk):
    task = get_object_or_404(Task, pk=pk)
    return render(request, "tasks/list.html#task-row", {"task": task})


@require_GET
def stats(request):
    total = Task.objects.count()
    done = Task.objects.filter(done=True).count()
    data = {
        "total": total,
        "done": done,
        "open": total - done,
    }
    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)


def not_found():
    return JsonResponse({"error": "Task not found"}, status=404)


@method_decorator(csrf_exempt, name="dispatch")
class TaskDetail(View):
    def get(self, request, pk):
        task = Task.objects.filter(pk=pk).first()
        if task is None:
            return not_found()
        return JsonResponse(task_to_dict(task))

    def patch(self, request, pk):
        task = Task.objects.filter(pk=pk).first()
        if task is None:
            return not_found()
        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))

    def delete(self, request, pk):
        task = Task.objects.filter(pk=pk).first()
        if task is None:
            return not_found()
        task.delete()
        return HttpResponse(status=204)

Toutes les leçons de API JSON

Entraînez-vous par vous-même : Playground Django