لا يحرر إلا ناشر الإعلان
جزء من قسم واجهات العرض المعتمدة على الأصناف في رحلة Django على Coddy. الدرس 16 من 18.
سجّل الدخول باسم grace وافتح /jobs/python-developer-brightline/edit/: نشرت ada إعلان الوظيفة، ويمكن لـ grace تغييره. تعرض صفحات الوظائف Edit للناشر فقط، لكن يمكن لأي شخص كتابة العنوان أو إرسال طلب POST، لذا يجب أن يرفض العرض نفسه الطلب.
يستدعي UserPassesTestMixin طريقة تكتبها أنت، وهي test_func()، قبل تشغيل العرض. تسمح True بمرور الطلب؛ وتُرجع False استجابة 403 محظور للمستخدم الذي سجّل الدخول، سواء كان الطلب GET أو POST. في موقع للوصفات، لا يُسمح لأحد بتغيير وصفة منشورة:
class RecipeUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Recipe
fields = ["title", "minutes"]
def test_func(self):
return not self.get_object().publishedيُجرى الاختبار قبل أن يبحث العرض عن الصف، لذا لا يكون self.object موجودًا بعد. يعثر self.get_object() على الصف من عنوان URL، بالطريقة نفسها التي سيتبعها العرض.
التحدي
متوسطلا يجوز تعديل الوظيفة أو حذفها إلا لمن نشرها:
- أضف
UserPassesTestMixinإلىJobUpdateViewوJobDeleteView، بعدLoginRequiredMixin. - ينجح الاختبار فقط للمستخدم الذي نشر الوظيفة. أما أي شخص آخر فسيحصل على
403 Forbidden، عند استخدام GET وPOST.
اضغط على «تشغيل»، وسجّل الدخول باسم grace وافتح صفحة التعديل المذكورة أعلاه.
جرّب بنفسك
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import CreateView, DeleteView, DetailView, ListView, TemplateView, UpdateView
from .models import Job
class HomeView(TemplateView):
template_name = "jobs/home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["count"] = Job.objects.count()
context["latest"] = Job.objects.order_by("-posted").first()
return context
class AboutView(TemplateView):
template_name = "jobs/about.html"
class JobListView(ListView):
model = Job
context_object_name = "jobs"
ordering = ["-posted"]
paginate_by = 5
def get_queryset(self):
jobs = super().get_queryset()
city = self.request.GET.get("city")
if city:
jobs = jobs.filter(city=city)
return jobs
class JobDetailView(DetailView):
model = Job
class JobCreateView(LoginRequiredMixin, CreateView):
model = Job
fields = ["title", "company", "city", "salary", "description"]
def form_valid(self, form):
form.instance.posted_by = self.request.user
return super().form_valid(form)
class JobUpdateView(LoginRequiredMixin, UpdateView):
model = Job
fields = ["title", "company", "city", "salary", "description"]
class JobDeleteView(LoginRequiredMixin, DeleteView):
model = Job
success_url = reverse_lazy("jobs:list")
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس واجهات العرض المعتمدة على الأصناف
4عروض التحرير
CreateViewالانتقال إلى الوظيفة الجديدةتدرّب بنفسك: Playground لـ Django