Trilla
Trilla

Reputation: 771

Slugify not saving title as slug Django 2: NoReverseMatch error

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

Answers (1)

michjnich
michjnich

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

Related Questions