Chỉ người đăng mới chỉnh sửa
Thuộc phần View dựa trên lớp trong hành trình Django của Coddy. Bài học 16 trên 18.
Đăng nhập bằng tài khoản grace rồi mở /jobs/python-developer-brightline/edit/: ada đã đăng tin tuyển dụng đó, và grace có thể thay đổi tin này. Trang tuyển dụng chỉ hiển thị Edit với người đăng, nhưng bất kỳ ai cũng có thể nhập địa chỉ hoặc gửi yêu cầu POST, nên chính view phải từ chối.
UserPassesTestMixin gọi một phương thức do bạn viết, test_func(), trước khi view chạy. Nếu phương thức trả về True, yêu cầu sẽ được xử lý. Nếu phương thức trả về False, người dùng đã đăng nhập sẽ nhận phản hồi 403 Forbidden, dù yêu cầu là GET hay POST. Một trang web về công thức nấu ăn không cho phép ai thay đổi công thức đã xuất bản:
class RecipeUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Recipe
fields = ["title", "minutes"]
def test_func(self):
return not self.get_object().publishedPhép kiểm tra chạy trước khi view tìm hàng trong cơ sở dữ liệu, nên self.object chưa tồn tại. self.get_object() tìm hàng dựa trên URL, giống như cách view sẽ làm.
Thử thách
Trung bìnhChỉ người đăng tin tuyển dụng mới có thể chỉnh sửa hoặc xóa tin đó. Trong jobs/views.py, thêm UserPassesTestMixin vào JobUpdateView và JobDeleteView, sau LoginRequiredMixin. Bài kiểm tra chỉ đạt khi người dùng là người đã đăng tin tuyển dụng; những người khác sẽ nhận lỗi 403 Forbidden với cả yêu cầu GET và POST.
Đăng nhập bằng tài khoản grace (coddy-pass-123) rồi mở /jobs/python-developer-brightline/edit/: ada đã đăng tin này, nên bạn sẽ thấy 403 Forbidden.
Tự làm thử
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")
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 View dựa trên lớp
4Chỉnh sửa view
CreateViewĐăng tin tuyển dụng mớiTự luyện tập: Playground Django