Reputation: 21
Every time I create a post in my website I always get a NoReverseMatch error when it redirects to the detail view of the app. I can't find the answer in the internet.
Views.py:
from django.shortcuts import render
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from . import forms
from . import models
# Create your views here.
class AnnouncementListView(generic.ListView,LoginRequiredMixin):
model = models.Announcement
class AnnouncementDetailView(generic.DetailView, LoginRequiredMixin):
model = models.Announcement
class AnnouncementUpdateView(generic.UpdateView, LoginRequiredMixin):
model = models.Announcement
form_class = forms.AnnouncementForm
class AnnouncementCreateView(generic.CreateView, LoginRequiredMixin):
model = models.Announcement
form_class = forms.AnnouncementForm
class AnnouncementDeleteView(generic.DeleteView, LoginRequiredMixin):
model = models.Announcement
success_url = reverse_lazy('announcement:single')
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user_id=self.request.user.id)
def delete(self, *args, **kwargs):
messages.success(self.request, "Post Deleted")
return super().delete(*args, **kwargs)
Urls.py:
from django.urls import path
from . import views
app_name = 'announcement'
urlpatterns = [
path('create/', views.AnnouncementCreateView.as_view(), name='create'),
path('', views.AnnouncementListView.as_view(), name='list'),
path('posts/<int:pk>/', views.AnnouncementDetailView.as_view(), name='single'),
path('delete/<int:pk>/', views.AnnouncementDeleteView.as_view(), name='destroy'),
]
announcement_detail.html:
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>{{announcement.title}}</h1>
<p>{{announcement.text}}</p>
<span>{{announcement.date}}</span>
<a href="{% url 'announcement:destroy' %} "><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eraser-fill" viewBox="0 0 16 16">
<path d="M8.086 2.207a2 2 0 0 1 2.828 0l3.879 3.879a2 2 0 0 1 0 2.828l-5.5 5.5A2 2 0 0 1 7.879 15H5.12a2 2 0 0 1-1.414-.586l-2.5-2.5a2 2 0 0 1 0-2.828l6.879-6.879zm.66 11.34L3.453 8.254 1.914 9.793a1 1 0 0 0 0 1.414l2.5 2.5a1 1 0 0 0 .707.293H7.88a1 1 0 0 0 .707-.293l.16-.16z"/>
</svg></a>
</div>
{% endblock %}
Error:
Upvotes: 1
Views: 98
Reputation: 476594
You need to pass the primary key of the announcement to destroy:
{% url 'announcement:destroy' announcement.pk %}
But a delete view will not be triggered with a GET request, but with a POST request, this is because a GET request is not supposed to create/update/remove entities.
You thus need to make a mini-form:
<form method="post" action="{% url 'announcement:destroy' announcement.pk %}">
{% csrf_token %}
<button type="submit">delete</button>
</form>
Furthermore the mixins should be put before the view, since otherwise these end up at the end of the method resolution order (MRO):
class AnnouncementDeleteView(LoginRequiredMixin, generic.DeleteView):
# …
As @NKSM says, the success_url
of your AnnounceDeleteView
has the same problem. You should redirect to the list, or you should override get_success_url
, but here it makes no sense to redirect to the detail view of the removed item, since it is removed:
from django.urls import reverse_lazy
class AnnouncementDeleteView(LoginRequiredMixin, generic.DeleteView):
model = models.Announcement
success_url = reverse('announcement:list')
# …
Upvotes: 2