소유자만 수정하기
Coddy Django 여정의 사용자와 계정 섹션에 포함된 레슨. 16개 중 11번째.
이제 노트 페이지는 안전하지만, 편집 및 삭제 페이지는 그렇지 않습니다. /3/edit/와 /3/delete/에서는 여전히 어떤 노트든 열 수 있습니다. 더 나쁜 점은, 페이지를 열 필요조차 없다는 것입니다. 폼은 POST 요청이며, 누구나 페이지를 보지 않고도 /3/delete/로 POST 요청을 보낼 수 있습니다.
따라서 규칙은 링크한 페이지별이 아니라 뷰별로 적용됩니다. 번호로 행을 불러오는 모든 뷰는 누가 해당 행을 불러올 수 있는지 그곳에서 결정해야 합니다. GET과 POST를 모두 처리하는 뷰에서 조회가 어디에 있는지 살펴보세요.
def ticket_close(request, pk):
ticket = ... # 조회 작업: 모든 요청마다 실행됩니다
if request.method == "POST":
ticket.closed = True
ticket.save()
return redirect("tickets:list")
return render(request, "tickets/close.html", {"ticket": ticket})첫 번째 줄은 if request.method == "POST" 분기보다 먼저 실행됩니다. 그곳의 조회가 낯선 사용자의 접근을 거부하면 GET 요청과 POST 요청 모두에 404를 반환하고, 아무것도 변경되지 않습니다.
챌린지
쉬움notes/views.py에서 note_edit와 note_delete가 사용자가 소유하지 않은 노트를 거부하도록 하세요. 다른 사용자의 노트는 GET과 POST 모두에서 404 응답을 반환하며, 변경되지 않은 상태로 유지됩니다. 자신의 노트는 계속 수정하고 삭제할 수 있습니다.
실행을 누르고 bob으로 로그인한 다음(비밀번호는 coddy-pass-123) /1/edit/을 여세요.
직접 해보기
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})
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
사용자와 계정의 모든 레슨
직접 연습해 보세요: Django 플레이그라운드