Home > OS >  Trying to revert from class based detail view to a function based view but I keep getting a NoRevers
Trying to revert from class based detail view to a function based view but I keep getting a NoRevers

Time:08-13

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:\Users\mikha\bug_env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\core\handlers\base.py", line 204, in _get_response
    response = response.render()
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\response.py", line 105, in render
    self.content = self.rendered_content
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\response.py", line 83, in rendered_content
    return template.render(context, self._request)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\backends\django.py", line 61, in render
    return self.template.render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 176, in render
    return self._render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 168, in _render
    return self.nodelist.render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 977, in render
    return SafeString(''.join([
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 978, in <listcomp>
    node.render_annotated(context) for node in self
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 938, in render_annotated
    return self.render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\loader_tags.py", line 153, in render
    return compiled_parent._render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 168, in _render
    return self.nodelist.render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 977, in render
    return SafeString(''.join([
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 978, in <listcomp>
    node.render_annotated(context) for node in self
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 938, in render_annotated
    return self.render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\loader_tags.py", line 65, in render
    result = block.nodelist.render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 977, in render
    return SafeString(''.join([
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 978, in <listcomp>
    node.render_annotated(context) for node in self
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 938, in render_annotated
    return self.render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\defaulttags.py", line 214, in render
    nodelist.append(node.render_annotated(context))
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\base.py", line 938, in render_annotated
    return self.render(context)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\template\defaulttags.py", line 442, in render
    url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\urls\base.py", line 86, in reverse
    return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
  File "C:\Users\mikha\bug_env\lib\site-packages\django\urls\resolvers.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 >
        <img  src="{{ ticket.author.profile.image.url }} " alt="">
        <div >
          <div >
            <a  href="{% url 'post_single' ticket.slug %}">{{ ticket.author }}</a>
            <small >{{ ticket.date_posted }}</small>
            <small >{{ ticket.status|yesno:'Open, Closed'  }}</small>
          </div>
          <h2><a  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

CodePudding user response:

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.

  • Related