Menu
CoddyTech

LoginRequiredMixin

Parte de la sección Vistas basadas en clases del Journey de Django de Coddy. Lección 14 de 18.

Ahora mismo cualquiera puede publicar, editar o eliminar un trabajo sin tener una cuenta. Una clase no tiene una única función a la que añadir @login_required, así que Django te ofrece un mixin: una clase pequeña que añades a las clases padre de una vista para incorporar un comportamiento adicional.

from django.contrib.auth.mixins import LoginRequiredMixin


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

Ahora, a un visitante que no ha iniciado sesión se le redirige a /accounts/login/?next=/recipes/new/ antes de que se ejecute la vista, tanto en GET como en POST. Después de iniciar sesión, next lo lleva de vuelta.

El mixin va primero. Todas las vistas empiezan en un método llamado dispatch(), y Python lo busca en las clases padre de izquierda a derecha. Si escribes (CreateView, LoginRequiredMixin), prevalece el propio dispatch() de la vista, la comprobación del inicio de sesión nunca se ejecuta y no recibes ningún aviso.

challenge icon

Desafío

Intermedio

Solo los usuarios que hayan iniciado sesión pueden publicar, editar o eliminar ofertas de empleo. En jobs/views.py, añade LoginRequiredMixin a JobCreateView, JobUpdateView y JobDeleteView. La lista de ofertas y las páginas de cada oferta siguen abiertas a todo el mundo.

Pulsa Post a job: llegarás a la página de inicio de sesión, donde ada inicia sesión con coddy-pass-123.

Pruébalo tú mismo

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")

Todas las lecciones de Vistas basadas en clases

Practica por tu cuenta: Playground de Django