Menu
CoddyTech

Yêu cầu quyền hạ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 13 trên 16.

Trang mới /all/ liệt kê ghi chú của mọi người dùng, dành cho những người xử lý yêu cầu hỗ trợ. is_staff là một công tắc áp dụng cho mọi thứ; trang này cần một quy tắc cụ thể hơn.

Với mỗi mô hình, migrate tạo bốn quyền: thêm, chỉnh sửa, xóa và xem. Mỗi quyền được đặt tên bằng nhãn ứng dụng và một tên mã, như shop.change_product. Bạn cấp các quyền này cho người dùng hoặc nhóm trên trang của người dùng trong trang quản trị. Người dùng cấp cao có tất cả các quyền.

Một decorator kiểm tra một quyền:

from django.contrib.auth.decorators import permission_required


@permission_required("shop.change_product", raise_exception=True)
def edit_prices(request):
    ...

Nếu không có raise_exception=True, người dùng không có quyền sẽ được chuyển đến trang đăng nhập, dù họ đã đăng nhập. Nếu có, họ sẽ nhận lỗi 403. Trong một view, request.user.has_perm("shop.change_product") thực hiện cùng phép kiểm tra; trong một template, dùng {% if perms.shop.change_product %}.

challenge icon

Thử thách

Trung bình

Mở /all/ chỉ dành cho nhân viên hỗ trợ.

  1. Trong notes/views.py, chỉ cho phép người dùng có quyền tích hợp sẵn của Django để xem ghi chú mở all_notes. Những người khác nhận lỗi 403 Forbidden, không phải trang đăng nhập.
  2. Trong base.html, sau liên kết Stats, thêm liên kết All notes đến /all/, chỉ hiển thị với người dùng có quyền đó.

Mở /all/ với tư cách carol: trang này liệt kê cả ba ghi chú. Với tư cách bob: 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.core.exceptions import PermissionDenied
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):
    if not request.user.is_staff:
        raise PermissionDenied
    context = {"user_count": User.objects.count(), "note_count": Note.objects.count()}
    return render(request, "notes/stats.html", context)


def all_notes(request):
    notes = Note.objects.select_related("owner")
    return render(request, "notes/all_notes.html", {"notes": notes})
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

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

Tự luyện tập: Playground Django