Django视图跳转异常:点击幻灯片打开错误详情页求助
Django URL匹配踩坑:点幻灯片却打开子内容详情?我来帮你排查!
我是Django新手,已创建两个独立视图与URL配置,但启动开发服务器后,点击幻灯片试图打开slides_detail.html时,却打开了sub_detail.html。二者名称无相似性,幻灯片与子内容同属一个HTML文档、URL及视图模块,且无报错信息,恳请帮忙排查问题。
先看看你提供的代码片段:
你现有的代码
URL配置
path('<int:sub_id>/', views.sub_detail, name='sub_detail'), path('<int:slides_id>/', views.slides_detail, name='slides_detail'),
视图代码
# 展示特定子内容详情 def sub_detail(request, sub_id): subcontent = get_object_or_404(SubContent, pk=sub_id) context = { 'subcontent': subcontent, } return render(request, 'home/sub_detail.html', context) # 展示特定幻灯片内容详情 def slides_detail(request, slides_id): slides = Slides.objects.get(pk=slides_id) context = { 'slides': slides, } return render(request, 'home/slides_detail.html', context)
幻灯片HTML代码
{% for slides in slides %} <div class="swiper-slide"> <div class="card"> <a href="{% url 'slides_detail' slides.id %}"> <img src="{{ slides.image.url }}" class="card-img-top img-height" alt="..."></a> <div class="card-body bg-dark"> <h5 class="card-title text-light font-weight-bold text-center">{{ slides.title }}</h5> </div> </div> </div> {% endfor %}
子内容HTML代码(部分)
{% for sub in subcontent %} {% if forloop.counter|divisibleby:2 %} <div class="row"> {% if sub.image %} <div class="col-md-6 section-index-img"> <img src="{{ sub.image.url }}" class="rounded img-fluid" alt=""/> </div> {% endif %} <div class="col-md-6"> <a href="{% url 'sub_detail' sub.id %}"> <h4>{{ sub.title }}</h4> </a> <p class="text-muted">{{ sub.description | linebreaks }}</p> </div> </div> {% else %} <!-- 其他内容 --> {% endif %} {% endfor %}
问题出在哪?URL匹配顺序搞的鬼!
Django的路由是从上到下挨个匹配的,只要找到第一个符合规则的路径,就直接跳转,不会往下看后面的规则。你现在这两个URL规则:
path('<int:sub_id>/', ...)path('<int:slides_id>/', ...)
它们的结构完全一样——都是“一个整数”的路径,Django才不管你参数名叫sub_id还是slides_id,只要路径是/数字/,就会先匹配到上面的sub_detail路由,自然就打开了子内容的页面,根本没机会触发下面的幻灯片视图!
怎么修复?给路由加唯一前缀!
最简单的办法就是给两个路由加上不同的前缀,让它们的路径结构不一样,比如:
修改后的URL配置
# 子内容详情加个/sub/前缀 path('sub/<int:sub_id>/', views.sub_detail, name='sub_detail'), # 幻灯片详情加个/slides/前缀 path('slides/<int:slides_id>/', views.slides_detail, name='slides_detail'),
这样改完之后,子内容的链接会变成/sub/1/,幻灯片的链接变成/slides/1/,Django就能准确区分两个路由了,不会再串页。
额外给你提两个小问题,提前避坑
- 幻灯片视图的报错风险:你现在
slides_detail里用了Slides.objects.get(pk=slides_id),如果用户访问了一个不存在的幻灯片ID,会直接抛出服务器错误。建议改成和sub_detail一样用get_object_or_404,这样会返回友好的404页面:
from django.shortcuts import get_object_or_404 def slides_detail(request, slides_id): slides = get_object_or_404(Slides, pk=slides_id) context = { 'slides': slides, } return render(request, 'home/slides_detail.html', context)
- 模板变量名冲突:幻灯片模板里写了
{% for slides in slides %},这里循环变量和上下文里的变量同名了,会导致循环逻辑出问题(比如循环到最后变量会被覆盖)。建议把循环变量改成单数slide:
{% for slide in slides %} <div class="swiper-slide"> <div class="card"> <a href="{% url 'slides_detail' slide.id %}"> <img src="{{ slide.image.url }}" class="card-img-top img-height" alt="..."></a> <div class="card-body bg-dark"> <h5 class="card-title text-light font-weight-bold text-center">{{ slide.title }}</h5> </div> </div> </div> {% endfor %}
内容的提问来源于stack exchange,提问作者Mar Sil
相关产品推荐
相关产品推荐

