Menu
CoddyTech

LoginRequiredMixin

Thuộc phần View dựa trên lớp trong hành trình Django của Coddy. Bài học 14 trên 18.

Hiện tại, bất kỳ ai cũng có thể đăng tin tuyển dụng, chỉnh sửa hoặc xóa tin mà không cần tài khoản. Lớp không có một hàm duy nhất để gắn @login_required vào, nên Django cung cấp cho bạn một mixin: một lớp nhỏ mà bạn thêm vào danh sách lớp cha của một view để bổ sung một hành vi.

from django.contrib.auth.mixins import LoginRequiredMixin


class RecipeCreateView(LoginRequiredMixin, CreateView):
    model = Recipe
    fields = ["title", "minutes"]

Giờ đây, khách truy cập chưa đăng nhập sẽ được chuyển đến /accounts/login/?next=/recipes/new/ trước khi view chạy, dù là GET hay POST. Sau khi đăng nhập, next sẽ đưa họ quay lại.

Mixin phải đứng đầu tiên. Mọi view đều bắt đầu trong một phương thức có tên dispatch(), và Python tìm phương thức này trong các lớp cha theo thứ tự từ trái sang phải. Nếu viết (CreateView, LoginRequiredMixin), dispatch() của chính view sẽ được ưu tiên, bước kiểm tra đăng nhập sẽ không bao giờ chạy và bạn cũng không nhận được cảnh báo nào.

challenge icon

Thử thách

Trung bình

Chỉ người dùng đã đăng nhập mới có thể đăng, chỉnh sửa hoặc xóa tin tuyển dụng. Trong jobs/views.py, thêm LoginRequiredMixin vào JobCreateView, JobUpdateView và JobDeleteView. Danh sách việc làm và các trang việc làm vẫn mở cho tất cả mọi người.

Nhấn Post a job: bạn sẽ đến trang đăng nhập, tại đó ada đăng nhập bằng coddy-pass-123.

Tự làm thử

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(CreateView):
    model = Job
    fields = ["title", "company", "city", "salary", "description"]


class JobUpdateView(UpdateView):
    model = Job
    fields = ["title", "company", "city", "salary", "description"]


class JobDeleteView(DeleteView):
    model = Job
    success_url = reverse_lazy("jobs:list")

Tất cả bài học trong View dựa trên lớp

Tự luyện tập: Playground Django