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, antes de que se ejecute la vista, se redirige a los visitantes que no hayan iniciado sesión a /accounts/login/?next=/recipes/new/, tanto en GET como en POST. Después de iniciar sesión, next los devuelve a la página anterior.

El mixin va primero. Todas las vistas empiezan en un método llamado dispatch(), y Python busca este método en las clases padre de izquierda a derecha. Si se escribe (CreateView, LoginRequiredMixin), prevalece el propio dispatch() de la vista, la comprobación del inicio de sesión nunca se ejecuta y nadie te avisa.

challenge icon

Desafío

Intermedio

Solo los usuarios que hayan iniciado sesión pueden publicar, editar o eliminar ofertas de empleo:

  • Añade LoginRequiredMixin a JobCreateView, JobUpdateView y JobDeleteView.
  • La lista de ofertas de empleo y las páginas de cada oferta siguen abiertas para todos.

Pulsa Run y pulsa Post a job: llegarás a la página de inicio de sesión. Inicia sesión como ada, con la contraseña 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