如何在Django中用get_absolute_url将博客路径改为字符串而非整数
修改Django博客路径为字符串Slug的详细步骤
嘿,作为Django新手碰到这个问题太正常了,别担心,咱们一步一步把文章路径从整数ID改成友好的字符串slug(也就是你要的/blog/my-blog-post这种形式):
1. 给博客模型添加Slug字段
首先得在你的BloggPost模型里加一个slug字段,用来存储文章的字符串路径。同时我们要让系统自动从标题生成slug,还得处理重复标题的情况:
from django.db import models from django.utils.text import slugify from django.contrib.auth.models import User from django.utils import timezone class BloggPost(models.Model): tittel = models.CharField(max_length=100) # 添加唯一的slug字段,确保每个文章路径不重复 slug = models.SlugField(unique=True, max_length=150, blank=False) innhold = models.TextField() date_posted = models.DateTimeField(default=timezone.now) author = models.ForeignKey(User, on_delete=models.CASCADE) image = models.ImageField(default='default.jpg', upload_to='blogg_foto') def __str__(self): return self.tittel def save(self, *args, **kwargs): # 如果还没设置slug,自动从标题生成 if not self.slug: self.slug = slugify(self.tittel) # 处理重复标题:如果slug已存在,加数字后缀 original_slug = self.slug counter = 1 while BloggPost.objects.filter(slug=self.slug).exists(): self.slug = f"{original_slug}-{counter}" counter += 1 # 调用父类的save方法完成保存 super().save(*args, **kwargs) def get_absolute_url(self): # 把原来的pk参数改成slug return reverse('bloggpost-detail', kwargs={'slug': self.slug})
2. 修改URL路由配置
把原来URL里的<int:pk>改成<slug:slug>,告诉Django我们现在用slug来匹配路径:
from django.urls import path from .views import BloggPostListViewHome, BloggPostListView, BloggPostDetailView from . import views urlpatterns = [ # 保留你的其他路由... path('blogg/<slug:slug>/', BloggPostDetailView.as_view(), name='bloggpost-detail'), ]
3. 更新详情视图(DetailView)
默认的DetailView是用pk来查询对象的,我们需要告诉它现在用slug字段来查询:
from django.views.generic import DetailView from .models import BloggPost class BloggPostDetailView(DetailView): model = BloggPost # 指定用来查询的字段是slug slug_field = 'slug' # 指定URL里的参数名是slug slug_url_kwarg = 'slug' # 如果你的模板文件名是默认的`bloggpost_detail.html`,这里不用额外设置
4. 数据库迁移
因为我们给模型加了新字段,必须运行迁移命令让数据库更新:
python manage.py makemigrations python manage.py migrate
注意:运行
makemigrations时,Django会提示你给现有文章设置slug值,选择选项1就能自动给所有旧文章生成slug,非常方便!
额外优化:后台自动生成Slug
如果你用Django Admin管理文章,可以在后台配置自动从标题生成slug,避免手动输入:
from django.contrib import admin from .models import BloggPost class BloggPostAdmin(admin.ModelAdmin): # 配置slug字段从tittel字段自动生成 prepopulated_fields = {'slug': ('tittel',)} admin.site.register(BloggPost, BloggPostAdmin)
这样操作完之后,你的文章路径就会变成/blogg/你的文章标题这种友好的字符串形式啦!
内容的提问来源于stack exchange,提问作者André Krosby
相关产品推荐
相关产品推荐

