Reputation: 414
I'm a newbie and I've been battling with an error while trying to display the detail page of a post. I've checked other answers relating to this question but the solutions still don't work for me.
This is the error I'm getting:
Reverse for 'blog_post' with no arguments not found. 1 pattern(s) tried: ['blog\\/post/(?P<slug>[-\\w]+)/$']
This is my model:
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique_for_date='publish')
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES,
default='draft')
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post', args=[str(self.slug)])
View functions:
class BlogHomePageView(ListView):
model = Post
template_name = 'blog/index.html'
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post.html'
slug_url_kwarg = 'slug'
query_pk_and_slug = True
Urlpatterns:
path('', BlogHomePageView.as_view(), name='blog_home'),
re_path(r'post/(?P<slug>[-\w]+)/$', PostDetailView.as_view(), name='blog_post'),
base.html
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav">
<div class="container">
<a class="navbar-brand" href="index.html">Toluwalemi</a>
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse"
data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false"
aria-label="Toggle navigation">
Menu
<i class="fas fa-bars"></i>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{% url 'blog_home' %}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'blog_about' %}">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'blog_post' %}">Sample Post</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'blog_contact' %}">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
detail page:
{% extends 'blog/base.html' %}
{% block title %}Post{% endblock %}
<!-- Page Header -->
{% block page_header %}
<div class="post-heading">
<h1>{{ post.title }}</h1>
<h2 class="subheading">Problems look mighty small from 150 miles up</h2>
<span class="meta">Posted by
<a href="#">{{ post.author }}</a>
on {{ post.publish }}</span>
</div>
{% endblock %}
<!-- Post Content -->
<article>
{% block content %}
<p>{{ post.body }}</p>
list page:
{% extends 'blog/base.html' %}
{% block title %}Home{% endblock %}
<!-- Page Header -->
{% block page_header %}
<div class="site-heading">
<h1>Toluwalemi's Blog</h1>
<span class="subheading">Official Blog</span>
</div>
{% endblock %}
<!-- Main Content -->
{% block content %}
{% for post in object_list %}
<div class="post-preview">
<a href="{{ post.get_absolute_url }}">
<h2 class="post-title">
{{ post.title }}
</h2>
Upvotes: 1
Views: 3214
Reputation: 414
So guys, I finally figured it out. My slug url is now working perfectly.
The error was actually coming from my list page. The url to the detail view wasn't written well. I didn't include a namespace. So instead of <a href="{{ post.get_absolute_url }}">
it becomes <a href="{% url 'blog:blog_post' post.slug %}">
I also deleted redundant lines of codes in my models and my views page.
Here is what it looks like now.
models.py:
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, default="")
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
body = models.TextField()
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
views.py
class BlogHomePageView(ListView):
model = Post
template_name = 'blog/index.html'
context_object_name = 'posts'
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post.html'
context_object_name = 'post'
blog/urls.py:
urlpatterns = [
path('', BlogHomePageView.as_view(), name='blog_home'),
path('post/<slug:slug>/', PostDetailView.as_view(), name='blog_post'),
]
list page(index.html):
{% extends 'blog/base.html' %}
{% block title %}Home{% endblock %}
<!-- Page Header -->
{% block page_header %}
<div class="site-heading">
<h1>Toluwalemi's Blog</h1>
<span class="subheading">Official Blog</span>
</div>
{% endblock %}
<!-- Main Content -->
{% block content %}
{% for post in posts %}
<div class="post-preview">
<a href="{% url 'blog:blog_post' post.slug %}">
<h2 class="post-title">
{{ post.title }}
</h2>
Upvotes: 1
Reputation: 16485
If you look at your URL definition, you can see that it expects an argument slug
:
re_path(r'post/(?P<slug>[-\w]+)/$', PostDetailView.as_view(), name='blog_post'),
which, by the way, could also be expressed as as of Django 2.0:
path('post/<slug:slug>/', PostDetailView.as_view(), name='blog_post'),
Now, the error message from the image shows clearly that you are calling the URL
template tag without said argument, it only has
href="{% url 'blog_post' %}"
and no slug argument is present.
You need to add the slug argument.
You have not even shown us the right template in your question where the line appears that is shown in the error message, so I cannot help further than this.
Upvotes: 2