如何将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差
修改方式如下:
- Urls.py改为:
path("<str:title>/", views.project_details, name="project_details") - 视图改为:
def project_details(request, title): project = get_object_or_404(Project, title=title) - 模板传参改为
{% url 'project_details' title=project.title %}
内容的提问来源于stack exchange,提问作者swamptiger24
相关产品推荐
相关产品推荐

