Menu
CoddyTech

Chỉ dành cho nhân viên

Thuộc phần Người dùng và tài khoản trong hành trình Django của Coddy. Bài học 12 trên 16.

Trang mới /stats/ thống kê số người dùng và ghi chú. Trang này dành cho những người quản lý trang web, và bất kỳ người dùng nào đã đăng nhập đều có thể mở trang.

Đăng nhập là một chuyện; người dùng được phép làm gì lại là chuyện khác. User có một cờ dành cho những người quản lý trang web: is_staff, có giá trị true với những người được phép dùng trang quản trị.

Khi người dùng đã đăng nhập yêu cầu xem nội dung họ không được phép xem, phản hồi là 403 Forbidden: trang web biết bạn là ai và từ chối yêu cầu. Trong một view, hãy phát sinh PermissionDenied và Django sẽ gửi phản hồi 403. Một diễn đàn từ chối trả lời trong chủ đề đã khóa:

from django.core.exceptions import PermissionDenied


def thread_reply(request, pk):
    thread = get_object_or_404(Thread, pk=pk)
    if thread.locked:
        raise PermissionDenied
    ...

Trong template, cờ này nằm trên user, nên liên kết chỉ hiển thị với những người được phép truy cập. Liên kết chỉ giúp truy cập thuận tiện; phần kiểm tra trong view mới là lớp bảo vệ.

challenge icon

Thử thách

Dễ

Giữ /stats/ cho nhân viên.

  1. Trong notes/views.py, sửa stats để trả về lỗi 403 Forbidden cho mọi người dùng không phải nhân viên.
  2. Trong base.html, thêm liên kết Stats đến /stats/ sau New note, chỉ hiển thị liên kết này cho nhân viên.

Mở /stats/ bằng tài khoản ada (nhân viên): bạn sẽ thấy số liệu. Với tài khoản bob: lỗi 403 Forbidden. Mật khẩu coddy-pass-123.

Tự làm thử

from django.contrib.auth import login
from django.contrib.auth.decorators import login_not_required
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
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, owner=request.user)
    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, owner=request.user)
    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})


def stats(request):
    context = {"user_count": User.objects.count(), "note_count": Note.objects.count()}
    return render(request, "notes/stats.html", context)

Tất cả bài học trong Người dùng và tài khoản

Tự luyện tập: Playground Django