Menu
CoddyTech

Seul le propriétaire peut modifier

Fait partie de la section Utilisateurs et comptes du Journey Django de Coddy. Leçon 11 sur 16.

La page d’une note est maintenant sécurisée, mais pas ses pages de modification et de suppression : /3/edit/ et /3/delete/ permettent toujours d’ouvrir n’importe quelle note. Pire encore, il n’est même pas nécessaire de les ouvrir. Un formulaire envoie une requête POST, et n’importe qui peut envoyer une requête POST à /3/delete/ sans jamais voir la page.

La règle s’applique donc à chaque vue, et non à chaque page vers laquelle tu crées un lien : chaque vue qui charge une ligne à partir de son numéro décide à cet endroit qui peut la charger. Regarde où se trouve la recherche dans une vue qui gère à la fois GET et POST :

def ticket_close(request, pk):
    ticket = ...  # la recherche : elle s’exécute pour chaque requête
    if request.method == "POST":
        ticket.closed = True
        ticket.save()
        return redirect("tickets:list")
    return render(request, "tickets/close.html", {"ticket": ticket})

La première ligne s’exécute avant la branche if request.method == "POST". Si cette recherche vérifie aussi le propriétaire, un inconnu reçoit une réponse 404 pour la requête GET comme pour la requête POST, et rien ne change.

challenge icon

Défi

Facile

Dans notes/views.py, faites en sorte que note_edit et note_delete refusent les notes qui n'appartiennent pas à l'utilisateur. La note d'un autre utilisateur renvoie une erreur 404, pour les requêtes GET et POST, et reste inchangée. Vous pouvez toujours modifier et supprimer vos propres notes.

Connectez-vous en tant que bob (mot de passe coddy-pass-123) et ouvrez /1/edit/ : page 404 introuvable.

Essayez vous-même

from django.contrib.auth import login
from django.contrib.auth.decorators import login_not_required
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import get_object_or_404, redirect, render

from .forms import NoteForm
from .models import Note


def note_list(request):
    notes = Note.objects.filter(owner=request.user)
    return render(request, "notes/note_list.html", {"notes": notes})


def note_detail(request, pk):
    note = get_object_or_404(Note, pk=pk, owner=request.user)
    return render(request, "notes/note_detail.html", {"note": note})


def note_create(request):
    if request.method == "POST":
        form = NoteForm(request.POST)
        if form.is_valid():
            note = form.save(commit=False)
            note.owner = request.user
            note.save()
            return redirect("notes:detail", pk=note.pk)
    else:
        form = NoteForm()
    return render(request, "notes/note_form.html", {"form": form})


def note_edit(request, pk):
    note = get_object_or_404(Note, pk=pk)
    if request.method == "POST":
        form = NoteForm(request.POST, instance=note)
        if form.is_valid():
            form.save()
            return redirect("notes:detail", pk=note.pk)
    else:
        form = NoteForm(instance=note)
    return render(request, "notes/note_form.html", {"form": form, "note": note})


def note_delete(request, pk):
    note = get_object_or_404(Note, pk=pk)
    if request.method == "POST":
        note.delete()
        return redirect("notes:list")
    return render(request, "notes/note_confirm_delete.html", {"note": note})


@login_not_required
def signup(request):
    if request.method == "POST":
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            return redirect("notes:list")
    else:
        form = UserCreationForm()
    return render(request, "notes/signup.html", {"form": form})
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Utilisateurs et comptes

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