Django中如何自动生成slug?搭建博客时根据文章标题生成URL对应slug的方法
Django 博客自动生成标题Slug实现方案
方案1:使用Django内置工具手动实现(无第三方依赖)
这是最轻量化的实现方式,不需要额外安装依赖,适合大部分场景。
步骤1:定义博客模型
首先在你的models.py中定义文章模型,新增slug字段:
from django.db import models from django.utils.text import slugify class Post(models.Model): title = models.CharField("文章标题", max_length=120) content = models.TextField("文章内容") # slug字段设置为唯一,允许创建时为空,后续自动生成 slug = models.SlugField("URL标识", max_length=100, unique=True, blank=True) create_time = models.DateTimeField("发布时间", auto_now_add=True)
步骤2:重写save方法自动生成slug
在Post模型中新增save方法的重写逻辑,创建文章时如果没有手动指定slug,就自动从标题生成,同时处理重复slug的问题:
def save(self, *args, **kwargs): # 仅当slug为空时自动生成,避免修改标题后旧URL失效 if not self.slug: base_slug = slugify(self.title) slug = base_slug count = 1 # 检查slug是否重复,重复则追加数字后缀 while Post.objects.filter(slug=slug).exists(): slug = f"{base_slug}-{count}" count += 1 self.slug = slug super().save(*args, **kwargs)
中文标题适配
Django内置的slugify默认不支持中文,会直接把中文过滤为空,如果你需要处理中文标题,可以引入拼音转换库处理:
- 安装pypinyin:
pip install pypinyin - 修改生成逻辑:
from pypinyin import lazy_pinyin def save(self, *args, **kwargs): if not self.slug: # 中文转拼音后再生成slug pinyin_title = ' '.join(lazy_pinyin(self.title)) base_slug = slugify(pinyin_title) # 后续重复判断逻辑和上面一致 slug = base_slug count = 1 while Post.objects.filter(slug=slug).exists(): slug = f"{base_slug}-{count}" count += 1 self.slug = slug super().save(*args, **kwargs)
方案2:使用第三方库django-autoslug简化实现
如果不想自己处理重复判断等逻辑,可以直接用成熟的第三方库:
- 安装库:
pip install django-autoslug - 模型定义直接使用AutoSlugField:
from autoslug import AutoSlugField from django.db import models class Post(models.Model): title = models.CharField("文章标题", max_length=120) content = models.TextField("文章内容") # 直接指定从title字段生成slug,自动处理重复 slug = AutoSlugField(populate_from='title', unique=True) create_time = models.DateTimeField("发布时间", auto_now_add=True)
Admin后台配置(可选)
如果需要在Django Admin后台编辑文章时实时预览slug生成效果,可以在admin.py中配置prepopulated_fields:
from django.contrib import admin from .models import Post @admin.register(Post) class PostAdmin(admin.ModelAdmin): prepopulated_fields = {"slug": ("title",)}
配置后在admin后台输入标题的时候,slug字段会实时自动填充。
配置URL路由
生成slug后,你就可以用slug作为URL参数匹配文章了,路由配置示例:
# urls.py from django.urls import path from . import views urlpatterns = [ path('post/<slug:slug>/', views.post_detail, name='post_detail'), ]
对应的视图函数示例:
# views.py from django.shortcuts import get_object_or_404, render from .models import Post def post_detail(request, slug): post = get_object_or_404(Post, slug=slug) return render(request, 'post_detail.html', {'post': post})
内容的提问来源于stack exchange,提问作者Zakariya ANAYNE
相关产品推荐
相关产品推荐

