如何在没有任何前后的情况下对 django 中的所有 url 使用 slug?

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

我希望所有 djaango urls 默认使用前后不带任何参数的 slug 字段 只有一个 url 可以使用此方法

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"),
]

这是我的django博客代码, 我不想在 url 中写文章或类别 & ...,只是 slug

我的网站。com/article-slug ... 我的网站.com/category-slug

它将始终触发 Article 视图,无论该 slug 是否存在 Article。因此,您应该使 URL 模式不重叠,以便可以触发其他视图,例如:

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

如果你想要一个接受单个 slug 的路径,你应该定义一个视图来查看是否有 Article 和那个 slug,如果不是 Category 并且如果Product 情况并非如此,因此您在视图中而不是在 URL 模式中实现了该逻辑。

@WillemVanOlsem 是对的,你必须这样写一个视图:

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')

然后

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

...如果我没记错的话。这应该是它的精髓。 我没有测试这段代码,只是在这里输入它,所以如果它不起作用请告诉我,我会帮助修复它。

请注意,如果有文章与某些类别具有相同的 slug,您将有偏好。