Menu
CoddyTech

للطاقم فقط

جزء من قسم المستخدمون والحسابات في رحلة Django على Coddy. الدرس 12 من 16.

تُحصي الصفحة الجديدة /stats/ عدد المستخدمين والملاحظات. وهي مخصصة للأشخاص الذين يديرون الموقع، ويمكن لأي مستخدم مسجّل الدخول فتحها.

تسجيل الدخول مسألة، وما يمكن للمستخدم فعله مسألة أخرى. لدى User علامتا حالة للأشخاص الذين يديرون الموقع: is_staff (يمكنه استخدام لوحة الإدارة) وis_superuser (لديه جميع الأذونات).

عندما يطلب مستخدم مسجّل الدخول شيئًا قد لا يكون مسموحًا له به، يكون الرد 403 Forbidden: «أعرف هويتك، والجواب لا». في العرض البرمجي، أطلق PermissionDenied وسيرسل Django استجابة 403. يرفض المنتدى الردود على موضوع مغلق:

from django.core.exceptions import PermissionDenied


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

في القالب، تكون العلامتان ضمن user، لذا لا يظهر الرابط إلا للأشخاص المسموح لهم بفتحه. الرابط وسيلة للتيسير؛ أما التحقق في العرض البرمجي فهو وسيلة الحماية.

challenge icon

التحدي

سهل
  • يعرض /stats/ خطأ 403 ممنوعًا لكل مستخدم ليس من الموظفين.
  • في base.html، بعد New note، يوجد رابط Stats إليه، ويظهر للموظفين فقط.

اضغط على تشغيل، وسجّل الدخول باسم ada (موظف)، ثم افتح /stats/. بعد ذلك جرّب bob. يستخدم كلاهما coddy-pass-123.

جرّب بنفسك

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)

جميع دروس المستخدمون والحسابات

تدرّب بنفسك: Playground لـ Django