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 ses pages de modification et de suppression ne le sont pas : /3/edit/ et /3/delete/ ouvrent toujours n’importe quelle note. Pire encore, il n’est même pas nécessaire de les ouvrir. Un formulaire est 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 vous créez un lien : chaque vue qui charge une ligne à partir de son numéro décide à cet endroit qui peut la charger. Regardez 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". Une recherche placée là, qui refuse l’accès aux personnes non autorisées, leur renvoie une erreur 404 pour la requête GET comme pour la requête POST, et rien n’est modifié.

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.

Cliquez sur Run, connectez-vous en tant que bob (mot de passe coddy-pass-123) et ouvrez /1/edit/.

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