Trying to revert from class based detail view to a function based view but I keep getting a NoReverseMatch error

Question:

I am creating a ticket project with some comment functionality and I know this sounds weird, since the tendency is usually to go from function based to class based. My problem lies in the fact that since the Detail View is designed to just be a Display View, trying to include a comment system on the same page proves to be rather difficult. Right now, I am simply trying to replicate the detail part of the ticket and I keep getting this error

Traceback


Traceback (most recent call last):
  File "C:Usersmikhabug_envlibsite-packagesdjangocorehandlersexception.py", line 47, in inner
    response = get_response(request)
  File "C:Usersmikhabug_envlibsite-packagesdjangocorehandlersbase.py", line 204, in _get_response
    response = response.render()
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplateresponse.py", line 105, in render
    self.content = self.rendered_content
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplateresponse.py", line 83, in rendered_content
    return template.render(context, self._request)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebackendsdjango.py", line 61, in render
    return self.template.render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 176, in render
    return self._render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 168, in _render
    return self.nodelist.render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 977, in render
    return SafeString(''.join([
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 978, in <listcomp>
    node.render_annotated(context) for node in self
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 938, in render_annotated
    return self.render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplateloader_tags.py", line 153, in render
    return compiled_parent._render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 168, in _render
    return self.nodelist.render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 977, in render
    return SafeString(''.join([
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 978, in <listcomp>
    node.render_annotated(context) for node in self
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 938, in render_annotated
    return self.render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplateloader_tags.py", line 65, in render
    result = block.nodelist.render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 977, in render
    return SafeString(''.join([
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 978, in <listcomp>
    node.render_annotated(context) for node in self
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 938, in render_annotated
    return self.render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatedefaulttags.py", line 214, in render
    nodelist.append(node.render_annotated(context))
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatebase.py", line 938, in render_annotated
    return self.render(context)
  File "C:Usersmikhabug_envlibsite-packagesdjangotemplatedefaulttags.py", line 442, in render
    url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
  File "C:Usersmikhabug_envlibsite-packagesdjangourlsbase.py", line 86, in reverse
    return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
  File "C:Usersmikhabug_envlibsite-packagesdjangourlsresolvers.py", line 729, in _reverse_with_prefix
    raise NoReverseMatch(msg)

Exception Type: NoReverseMatch at /main/
Exception Value: Reverse for 'post_single' with arguments '('',)' not found. 1 pattern(s) tried: ['main/(?P<slug>[-a-zA-Z0-9_]+)/\Z']

I thought displaying just the detail part would be as easy as this
function based view

post_single(request, slug)
    ticket = Ticket.objects.get(slug=slug)

    return render(request, 'tickets/improved.html', {'ticket':ticket})

But I keep getting that error, I’m not sure what’s wrong.

Here is the generic class based view

class TicketDetailView(DetailView):
    model = Ticket

urls.py

urlpatterns = [
    path('main/', TicketListView.as_view(), name='ticket-home'),
    path('main/<slug:slug>/', views.post_single, name='post_single'),
    path('user/<str:username>', UserTicketListView.as_view(), name='user-tickets'), 
    path('tickets/<int:pk>/', TicketDetailView.as_view(), name='ticket-detail'),
    path('tickets/new/', TicketCreateView.as_view(), name='ticket-create'),
    path('tickets/<int:pk>/update/', TicketUpdateView.as_view(), name='ticket-update'),
    path('tickets/<int:pk>/delete/', TicketDeleteView.as_view(), name='ticket-delete'),
    path('about/', views.about, name='tickets-about'),
]

TicketListView

class TicketListView(ListView):
    model = Ticket
    template_name = 'tickets/home.html'
    context_object_name = 'tickets'
    ordering = ['-date_posted']
    # paginate_by = 5
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        
        
        search_input = self.request.GET.get('search-area') or ''
        if search_input:
            context['tickets'] = context['tickets'].filter(title__startswith=search_input)
        context['search_input'] = search_input
        
        return context

template for ListView

{% for ticket in tickets %}
      <article class="media content-section">
        <img class="rounded-circle article-img" src="{{ ticket.author.profile.image.url }} " alt="">
        <div class="media-body">
          <div class="article-metadata">
            <a class="mr-2" href="{% url 'post_single' ticket.slug %}">{{ ticket.author }}</a>
            <small class="text-muted">{{ ticket.date_posted }}</small>
            <small class="text-muted">{{ ticket.status|yesno:'Open, Closed'  }}</small>
          </div>
          <h2><a class="article-title" href="{% url 'ticket-detail' ticket.id %}">{{ ticket.title }}</a></h2>
          
        </div>
      </article>
    {% endfor %}

Ticket models.py

class Ticket(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    assignee = models.ForeignKey(Profile, on_delete=models.SET_NULL, 
             blank=True, null=True)
    status = models.BooleanField(choices=MARKED, default=True)
    priority = models.TextField(choices=PRIORITIES, default='None', 
             max_length=10)
    label = models.CharField(choices=TYPES, default='Misc', 
             max_length=100)
    slug = models.SlugField()
    
    
    def __str__(self):
        return self.title
    
    def get_absolute_url(self):

Any help is much appreciated

Asked By: mdaw11

||

Answers:

You have to correct your SlugField empty values. If you have at least one empty slug it is passed as empty string '', so basically it tries to fetch first view of that two:

path('main/', TicketListView.as_view(), name='ticket-home'),
path('main/<slug:slug>/', views.post_single, name='post_single'),

As @Damoiskii said, learn about automating slug fields HERE. For now you can change those fields either in admin panel or in shell:

$ python manage.py shell
>>> from your_app.models import Ticket
>>> for ticket in Ticket.objects.all():
...     if not ticket.slug:
...         ticket.slug = "ticket-" + str(ticket.id)
...         ticket.save()

However, I don’t see the point to move to function based view. You can do literally anything in get() or post() methods in much better class based views.

Answered By: NixonSparrow
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.