Reputation: 771
Can't seem to get the slug
field to save because I am getting the error NoReverseMatch
.
Reverse for 'blog_detail' with arguments '(5, '')' not found. 1 pattern(s) tried: ['blogpost/(?P<pk>[0-9]+)/(?P<slug>[^/]+)$']
Could someone look over my code please as I am having trouble finding the problem?
urls.py
path('blogpost/<int:pk>/<str:slug>', news_views.BlogPostDetailView.as_view(), name='blog_detail'),
models.py
class BlogPost(models.Model):
title = models.CharField(max_length=190, null=True)
slug = models.SlugField(max_length=190, editable=False, unique=True, blank=True, default='')
def save(self, *args, **kwargs):
self.slug = slugify(self.title, allow_unicode=True)
super().save(*args, **kwargs)
def get_absolute_url(self):
kwargs = {
'pk': self.pk,
'slug': self.slug,
}
return reverse('blog_detail', kwargs=kwargs)
views.py
class BlogPostDetailView(DetailView):
context = {
'blog': BlogPost.objects.all(),
}
model = BlogPost
template_name = 'blog/blog_detail.html'
slug_field = 'slug'
slug_url_kwarg = 'slug'
homepage.html
<a href="{% url 'blog_detail' blog.pk blog.slug %}">{{ blog.title }}</a>
Upvotes: 0
Views: 85
Reputation: 3395
You can combine both the text and the pk into a single slug, and then simply reference that.
In the save method:
self.slug = slugify(f"{self.title} {str(self.id)}")
This also means that your slug will always be unique, because it includes the pk.
Then in urls.py set the path as:
'blogpost/<slug:slug>'
You won't need to pass pk
in the kwargs
any more then, but do note that existing data won't be magically fixed by this - if you re-save each record though the revised save
method should sort them out. You can also remove the pk reference from the template, as all you will need to pass now is the slug.
Upvotes: 0