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

如何将Django项目详情页URL从主键ID改为使用项目标题生成?

Django实现基于项目标题的详情页URL方案

步骤1:修改Models.py,新增自动生成的slug字段

slug是Django专门用于URL的友好字符串格式,会自动把中文、空格、特殊字符转为小写英文+连字符的格式,避免URL乱码或无效。修改你的模型代码如下:

from django.db import models
from django.utils.text import slugify # 导入slug生成工具

class Project(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    technology = models.CharField(max_length=20)
    image = models.FilePathField(path='projects/static/img/')
    live = models.URLField()
    source = models.URLField()
    # 新增slug字段,unique确保不重复,blank允许后台创建时不手动填写
    slug = models.SlugField(unique=True, blank=True, max_length=100)

    def __str__(self):
        return self.title
    
    # 重写save方法自动生成slug
    def save(self, *args, **kwargs):
        # 如果slug为空,就用title生成
        if not self.slug:
            self.slug = slugify(self.title)
        super().save(*args, **kwargs)

修改完成后执行python manage.py makemigrations和python manage.py migrate同步数据库变更。

步骤2:修改Urls.py的路径匹配规则

把原来的数字主键路径改为slug类型匹配:

from django.urls import path
from . import views

urlpatterns = [
    path("", views.project_index, name="projects"),
    # 替换原int:pk为slug:slug
    path("<slug:slug>/", views.project_details, name="project_details"),
]

步骤3:修改Views.py的查询逻辑

修改视图的入参和查询条件,context部分不需要调整:

from django.shortcuts import render, get_object_or_404 # 推荐用get_object_or_404处理不存在的情况
from .models import Project

def project_index(request):
    projects = Project.objects.all()
    context = {'projects': projects}
    return render(request, 'projects/project_index.html', context)

# 把入参pk改为slug
def project_details(request, slug):
    # 用slug查询对应项目
    project = get_object_or_404(Project, slug=slug)
    context = {'project': project} # 此处逻辑完全不需要修改
    return render(request, 'projects/project_details.html', context)

步骤4:修改模板中URL生成代码

你原来的模板里生成详情页链接的代码应该是类似这样的:

<a href="{% url 'project_details' pk=project.pk %}">{{ project.title }}</a>

替换为传slug参数即可:

<a href="{% url 'project_details' slug=project.slug %}">{{ project.title }}</a>

简化方案(不新增字段,直接用title匹配)

如果你不想新增slug字段,也可以直接用title匹配,不过要注意以下限制:

  • title字段必须设置unique=True避免重复
  • 标题里的特殊字符、空格会被URL编码,可读性比slug差
    修改方式如下:
  1. Urls.py改为:path("<str:title>/", views.project_details, name="project_details")
  2. 视图改为:def project_details(request, title): project = get_object_or_404(Project, title=title)
  3. 模板传参改为{% url 'project_details' title=project.title %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 22:18:01