Неправильная конфигурация по адресу /18/delete, проблема с представлениями Django
Я просмотрел другие вопросы, похожие на мою проблему, и не нашел решения, поэтому надеюсь, что кто-нибудь поможет мне понять, где я ошибся.
Я пытаюсь реализовать опцию удаления записи в программе моего блога, но она выдает следующую ошибку после нажатия кнопки "удалить":
Неправильная конфигурация в /18/delete/ В Deletepost отсутствует QuerySet. Определите Deletepost.model, Deletepost.queryset или переопределите Deletepost.get_queryset().
Я почти уверен, что это проблема с моим URLS.py, хотя что именно, я не могу понять.
ниже приведен код, о котором идет речь:
Views.py
# delete post
class Deletepost(LoginRequiredMixin, DeleteView):
form_class = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
urls.py
urlpatterns = [
# home
path('', views.postslist.as_view(), name='home'),
# add post
path('blog_post/', views.PostCreateView.as_view(), name='blog_post'),
# posts/comments
path('<slug:slug>/', views.postdetail.as_view(), name='post_detail'),
# edit post
path('<slug:slug>/edit/', views.Editpost.as_view(), name='edit_post'),
# delete post
path('<int:pk>/delete/', views.Deletepost.as_view(), name='delete_post'),
# likes
path('like/<slug:slug>', views.PostLike.as_view(), name='post_like'),
]
post.html
<a class="btn btn-outline-danger" href="{% url 'delete_post' post.id %}">Delete</a>
Спасибо за ваше время и извините за банальный вопрос, но вы, ребята, намного умнее меня!
Я думаю, что это должно быть model
а не form_class
так:
class Deletepost(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
@SunderamDubey's answer is correct. The test_func
will however not run, since this is method of the UserPassesTestMixin
[Django-doc], not LoginRequiredMixin
.
Но использование тестовой функции, как это сделано здесь, не эффективно: она будет дважды извлекать один и тот же объект из базы данных. Вы можете просто ограничить набор запросов, например:
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import DeleteView
class DeletePostView(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def get_queryset(self, *args, **kwargs):
return (
super().get_queryset(*args, **kwargs).filter(author=self.request.user)
)
Это будет выполнять фильтрацию на стороне базы данных, и таким образом возвращать 404 в случае, если вошедший пользователь не является автором объекта Post
, который вы хотите удалить.
В шаблоне необходимо сделать мини-форму для выполнения POST-запроса, например:
<form method="post" action="{% url 'delete_post' post.id %}"> {% csrf_token %} <button class="btn btn-outline-danger" type="submit">Delete</button> </form>
На мой взгляд, вам следует изменить url на следующий вариант 'path('delete/int:pk', views.Deletepost.as_view(), name='delete_post'),'
если не сработало, можно сделать так
def delete_post(request, post_id):
post = Post.objects.get(pk=post_id)
post.delete()
return redirect('blog:home')