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.