Search code examples
pythondjangodjango-urlsslugdjango-2.1

Combining more than one slug in the url


I'm trying to use two slug for generate the urls of a type of post. My site is divided in category and everyone of these have one or more post.

views.py

def singlePost(request, slug_post):
    blogpost = get_object_or_404(BlogPost, slug_post=slug_post)
    context = {"blogpost": blogpost}
    return render(request, "blog/single_post.html", context)


def singleCategory_postList(request, slug_category):
    category = get_object_or_404(Category, slug_category=slug_category)
    blogpost = BlogPost.objects.filter(category=category)
    context = {
            "category": category,
            "blogpost": blogpost,
            }
    return render(request, "blog/single_category.html", context)

urls.py that I use

path("category/<slug:slug_category>/", views.singleCategory_postList, name="single_category"),
path("<slug:slug_post>/", views.singlePost, name='single_blog_post'),

urls.py that I would like to use

path("<slug:slug_category>/", views.singleCategory_postList, name="single_category"),
path("<slug:slug_category>/<slug:slug_post>/", views.singlePost, name='single_blog_post'),

When I use the second couple of path it's shown to me this:

NoReverseMatch at /blog/gis/

Reverse for 'single_blog_post' with keyword arguments '{'slug_post': 'rete-dei-sottoservizi-quadro-normativo'}' not found. 1 pattern(s) tried: ['blog\/(?P[-a-zA-Z0-9_]+)\/(?P[-a-zA-Z0-9_]+)\/$']

models.py

class Category(models.Model):
    category_name = models.CharField(
                        max_length=50,
                        verbose_name="Categorie",
                        help_text="Every category must be not longer then 50 characters",
                        unique=True,
                        )
    slug_category = models.SlugField(
                verbose_name="Slug",
                unique=True,
                help_text="Slug is a field in autocomplete mode, but if you want you can modify its contents",
                )
....

    def __str__(self):
        return self.category_name

    def get_absolute_url(self): 
        return reverse("single_category", kwargs={"slug_category": self.slug_category})


class BlogPost(ModelPost, TimeManager):
    category = models.ForeignKey(
                    Category,
                    on_delete=models.CASCADE,
                    related_name="category_set",
                    verbose_name="Categorie",
                    help_text="Select a category for this article.You can select only one category.",
                    )
    keyconcepts = models.ManyToManyField(
                    KeyConcept,
                    related_name="keyconcept_blog_set",
                    help_text="Select a key concept for this article. You can select one or more key concepts.",
                    verbose_name="Concetti chiave",
                    )
.....

    def get_absolute_url(self): 
        return reverse("single_blog_post", kwargs={"slug_post": self.slug_post})

In this answer is explained how is possible to do the same thing that I try to do, but for my case don't work fine and I don't understand why.


Solution

  • But just like you said, the URL contains two slugs, so you need to pass them both in the reverse call. And you need to use the same names you have used in the URL pattern itself.

    return reverse("single_blog_post", kwargs={"slug": self.slug_post, "slug_category": self.category.slug_category})