Estoy creando un pequeño blog usando django. Quiero crear una función que permita al autor de la publicación eliminar y actualizar sus propias publicaciones. Luego encuentro que Django tiene LoginMixin para una vista genérica, pero solo bloquea a aquellos que no inician sesión.
El modelo de mi artículo es como el siguiente
class Article(models.Model): author = models.ForeignKey(User) updated = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=50) context = models.TextField() genre_choice = (('O','Others'),('P','Programming'),('L','Learning'),('E','Entertainment')) genre = models.CharField(max_length=2,choices=genre_choice,default='O') def __str__(self): return "{} - {}".format(self.title,self.author) def get_absolute_url(self): return reverse("article-detail",args=str(self.id))Esta es la vista de detalle del artículo genérico.
class ArticleDetail(DetailView): model = ArticleEn primer lugar, quiero agregar algo como esto en la plantilla de detalles:
{% if article.author == user.username%} <!-- Some a tag that directs to the update view --> {% endif %}Luego me doy cuenta de que esto solo oculta la etiqueta a, no puede evitar que otros usuarios toquen la URL de actualización, simplemente cambie la URL.
¿Hay alguna forma en que Django pueda restringir la actualización y eliminar los permisos para el usuario original simplemente usando la vista genérica? Incluso si ingresan directamente la URL de actualización, serán rechazados.
get_queryset en su UpdateView , de modo que el usuario solo pueda acceder a los elementos que creó. Utilice LoginRequiredMixin para asegurarse de que solo los usuarios registrados puedan acceder a la vista.
from django.contrib.auth.mixins import LoginRequiredMixin class UpdateArticle(LoginRequiredMixin, UpdateView): model = Article def get_queryset(self): queryset = super(UpdateArticle, self).get_queryset() queryset = queryset.filter(author=self.request.user) return queryset En la plantilla, compararía el author_id con la clave principal del usuario para decidir si mostrar el enlace o no.
{% if article.author_id == user.pk %}Una opción es crear su propio mixin/decorador para verificar si el usuario registrado es el autor, si no es así, vuelva a cargar/muestre un mensaje, etc.
Creo que una forma más segura ahora sería usar el mixin UserPassesTestMixin . En particular, puede heredarlo en su clase y cambiar su test_func() para verificar el autor. No olvide heredar también LoginRequiredMixin para asegurarse de que el usuario haya iniciado sesión:
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin class UpdateArticle(LoginRequiredMixin, UserPassesTestMixin, UpdateView): model = Article def test_func(self): thisArticle = self.get_object() if self.request.user == thisArticle.author: return True return FalseSi un usuario que no es el autor intenta actualizar el artículo, se devuelve el error '403 Prohibido', que es justo lo que desea en tal situación.