Django如何实现通过PK或Slug路由访问同一文章页面?
实现通过PK或Slug访问文章页面的解决方案
1. 调整路由配置
替换你现有的slug路由,改用正则路由匹配**数字(PK)或字符串(Slug)**格式的路径参数,避免路由冲突:
from django.urls import path, re_path from . import views urlpatterns = [ path('', views.index, name='index'), # 匹配数字或slug格式的标识符 re_path(r'^(?P<identifier>[\w-]+)/$', views.article_detail, name='article-detail'), ]
正则[\w-]+会匹配字母、数字、下划线和连字符,覆盖PK(纯数字)和Slug的常见格式。
2. 编写视图逻辑
在视图中先尝试按PK查询,失败后再按Slug查询,最后处理不存在的情况:
from django.shortcuts import get_object_or_404, render from .models import Article def article_detail(request, identifier): article = None # 先尝试按PK查询 try: article = Article.objects.get(pk=int(identifier)) except (ValueError, Article.DoesNotExist): # PK转换失败或不存在,尝试按Slug查询 try: article = Article.objects.get(slug=identifier) except Article.DoesNotExist: # 两者都不存在,返回默认文章或404页面 # 方案1:返回预设的默认文章(需模型有对应标识字段,比如is_default) article = get_object_or_404(Article, is_default=True) # 方案2:返回自定义“未找到”页面 # return render(request, 'article_not_found.html', status=404) return render(request, 'article_detail.html', {'article': article})
3. 模型层注意事项
确保Slug字段设置为唯一,避免查询时返回多条结果:
from django.db import models class Article(models.Model): title = models.CharField(max_length=200) slug = models.SlugField(unique=True) # 必须唯一 content = models.TextField() is_default = models.BooleanField(default=False) # 可选,用于标记默认文章 # 其他字段...
4. 模板渲染
在article_detail.html中正常渲染文章内容即可,无需额外区分来源是PK还是Slug。
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

