Construyendo un sitio web con referencia a un libro, hice una aplicación de blog.
Y descubrí que incluso los que no son autores pueden editar/eliminar la publicación que no escribieron. Así que he intentado arreglarlo de muchas maneras, pero hasta ahora he fallado.
Aquí están mis códigos.
modelos.py
class Post(models.Model): title = models.CharField('TITLE', max_length=50) slug = models.SlugField('SLUG', unique=True, allow_unicode=True) description = models.CharField('DESCRIPTION', max_length=100, blank=True) content = models.TextField('CONTENT') create_date = models.DateTimeField('Create Date', auto_now_add=True) modify_date = models.DateTimeField('Modify Date', auto_now=True) tag = TagField() author = models.ForeignKey(User, null=True) class Meta: ordering = ('-modify_date',) def __str__(self): return self.title def get_absolute_url(self): return reverse('blog:post_detail', args=(self.slug,)) def save(self, *args, **kwargs): if not self.id: self.slug = slugify(self.title, allow_unicode=True) super(Post, self).save(*args, **kwargs)vistas.py
class PostUpdateView(LoginRequiredMixin, edit.UpdateView): model = Post fields = ['title', 'slug', 'description', 'content', 'tag'] success_url = reverse_lazy('blog:index') def form_valid(self, form): form.instance.author = self.request.user return super(PostUpdateView, self).form_valid(form) class PostDeleteView(LoginRequiredMixin, edit.DeleteView): model = Post success_url = reverse_lazy('blog:index') def form_valid(self, form): form.instance.author = self.request.user return super(PostDeleteView, self).form_valid(form)A continuación se muestra el único código que funcionó y lo encontré en documentos (usando FormMixin con DetailView)
def post(self, request, *args, **kwargs): if not ((request.user==Post.author) or request.user.is_superuser): return HttpResponseForbidden() self.object = self.get_object() form = self.get_form() if form.is_valid(): return self.form_valid(form) else: return self.form_invalid(form) Funcionó, en algunos puntos, porque devuelve HttpResponseForbidden si el autor no intenta hacer clic en "enviar" en el formulario de actualización. Sin embargo, lo que quiero es que los no autores ni siquiera puedan acceder a la página de actualización.
También encontré la forma de personalizar dispatch() en stackoverflow pero no funcionó. No estoy seguro de si es adecuado en Django usar {% if not user == object.author %}{% else %}{% endif %} en plantillas como en PHP. Cualquier consejo será apreciado.
Gracias
El método de dispatch es el lugar correcto para hacer esto porque afectará a todas las solicitudes. Como habrá notado, poner el código de control de acceso en el método de post no afecta las solicitudes GET .
¿Cómo intentaste anular el dispatch ? Porque algo como esto debería funcionar:
from django.core.exceptions import PermissionDenied class PostUpdateView(LoginRequiredMixin, edit.UpdateView): # # All of your other view code here.... # def dispatch(self, request, *args, **kwargs): handler = super().dispatch(request, *args, **kwargs) user = request.user post = self.get_object() if not (post.author == user or user.is_superuser): raise PermissionDenied return handler Si es compatible con Python2, tendrá que cambiar la llamada super() a super(PostUpdateView, self).dispatch(request, *args, **kwargs) .