Home > Mobile >  How can use slug for all urls in django without anything before or after?
How can use slug for all urls in django without anything before or after?

Time:12-13

I want all djaango urls use slug field without any parameter before or after, by default just one url can use this metod

ex:

path('<slug:slug>', Article.as_View(), name="articledetail"),

path('<slug:slug>', Category.as_View(), name="category"),

path('<slug:slug>', Product.as_View(), name="productdetail"),

mysite .com/articleslug

mysite .com/categoryslug

mysite .com/productslug

How can I do it? Thank you

CodePudding user response:

It will always trigger the Article view, regardless if there is an Article for that slug. You thus should make the URL patterns non-overlapping such that the other views can be triggered, for example with:

path('article/<slug:slug>/', Article.as_View(), name="articledetail"),
path('category/<slug:slug>/', Category.as_View(), name="category"),
path('product/<slug:slug>/', Product.as_View(), name="productdetail"),

If you want a path that accepts a single slug, you should define a view that looks if there is an Article with that slug, if that is not the case a Category and if that is not the case a Product you thus implement that logic in the view, not in the URL patterns.

CodePudding user response:

@WillemVanOlsem is right, you will have to write a view like this:

from django.http import HttpResponseNotFound

def slug_router(request, slug):
    if Category.objects.filter(slug=slug).exists():
        return CategoryList.as_view()(request, slug=slug)
    elif Article.objects.filter(slug=slug).exists():
        return ArticleDetail.as_view()(request, slug=slug)
    else:
        return HttpResponseNotFound('404 Page not found')

And then

urlpatterns = [
    path('<slug:slug>', slug_router, name="slug"),
]

... if I'm not mistaken. This should be the jist of it. I didn't test this code, just typed it in here, so let me know if it doesn't work, I'll help to fix it.

Note that you'll have a preference if there are Articles with the same slug as some Categories.

CodePudding user response:

Views.py

class ArticleDetail(DetailView):
    def get_object(self):
        slug = self.kwargs.get('slug')
        article = get_object_or_404(Article.objects.published(), slug=slug)

        ip_address = self.request.user.ip_address
        if ip_address not in article.hits.all():
            article.hits.add(ip_address)

        return article

class CategoryList(ListView):
    paginate_by = 5
    template_name = 'blog/category_list.html'

    def get_queryset(self):
        global category
        slug = self.kwargs.get('slug')
        category = get_object_or_404(Category.objects.active(), slug=slug)
        return category.articles.published()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['category'] = category
        return context

urls.py

urlpatterns = [
    path('<slug:slug>', ArticleDetail.as_view(), name="detail"),
    path('<slug:slug>', CategoryList.as_view(), name="category"),
]

This is my django blog codes, I don't want write article or category & ... in urls, just slug

mysite .com/article-slug ... mysite .com/category-slug

now one url pattern ok but another url pattern don't work and have 404 error :(

  • Related