如何在没有任何前后的情况下对 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,您将有偏好。
我希望所有 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,您将有偏好。