You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django动态生成域名后URL:页面渲染及404处理是否合理?

问题背景

我正在搭建一个博客网站,为每篇文章设置了唯一标题,希望文章的URL格式为domain_name/<article_title>/。

现有两个模型:

class A(models.Model):
    title = models.CharField(max_length=500,unique=True)

class B(models.Model):
    title = models.CharField(max_length=500,unique=True)

app.urls.py配置:

urlpatterns = [
    path('',view.index,name="index"),
    path('contact/', contact, name="contact"),
    path('about/', about, name="about"),
    path('terms-and-conditions/', terms, name="terms_and_conditions"),
    path('privacy/', privacy, name="privacy"),
    path('<str:title>/', article_details, name="article_details"),
]

视图函数代码:

def article_details(request,title):
    if 'title_in_model_A':
          render 'some_page_A'
    
    if 'title_in_model_B:
          render 'some_page_B'

    render(request,'app/404.html')

project.urls配置:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('app.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


handler404 = 'app.views.view_404'

咨询两个问题:

  1. 这种页面渲染方式是否合理?
  2. 404请求是否处理正确?

问题1:页面渲染方式是否合理?

这种方式完全不合理,核心问题如下:

  • 判断逻辑完全失效:代码里的if 'title_in_model_A'是判断字符串非空,永远为True,会直接执行第一个render,后面的代码根本不会执行;第二个判断还存在语法错误(缺少闭合引号)。
  • 未实际查询数据库:当前代码没有去模型A、B中校验是否存在对应title的记录,只是写了假的判断条件,完全达不到区分不同模型文章的目的。
  • 可维护性极差:如果后续新增模型C、D,必须不断在视图里追加判断分支,不符合代码开闭原则。
  • URL参数风险:直接用title作为URL参数,若标题包含空格、特殊字符,会导致URL不规范,容易出现编码问题。

正确的实现思路

  1. 实际查询数据库,通过异常捕获判断记录是否存在:
from django.http import Http404

def article_details(request, title):
    try:
        obj = A.objects.get(title=title)
        return render(request, 'some_page_A.html', {'obj': obj})
    except A.DoesNotExist:
        try:
            obj = B.objects.get(title=title)
            return render(request, 'some_page_B.html', {'obj': obj})
        except B.DoesNotExist:
            raise Http404("文章不存在")
  1. 建议改用SlugField替代直接用title作为URL参数:给模型添加slug = models.SlugField(unique=True),生成符合URL规范的字符串(比如将My First Article转为my-first-article),URL配置改为path('<slug:slug>/', article_details, name="article_details"),避免特殊字符问题。
  2. 若后续模型较多,可抽象基类或使用通用视图,减少重复代码。

问题2:404请求是否处理正确?

当前处理方式不正确,问题点:

  • 状态码错误:直接render(request,'app/404.html')返回的是200 OK状态码,浏览器会认为这是正常响应,不利于SEO和客户端错误判断。
  • 未触发全局handler404:视图里的手动render不会调用配置的handler404视图,全局404配置形同虚设。
  • 逻辑走不到404分支:第一个判断永远为True,代码根本不会执行到最后一行的404渲染。

正确的处理方式

  1. 查询不到记录时抛出Http404异常,让Django自动调用全局配置的handler404:
from django.http import Http404

def article_details(request, title):
    # ...查询逻辑
    except B.DoesNotExist:
        raise Http404("文章不存在")
  1. 确保自定义的view_404视图返回正确的404状态码:
def view_404(request, exception):
    return render(request, 'app/404.html', status=404)

内容的提问来源于stack exchange,提问作者Manoj Kamble

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:55:29