Django自定义添加文章页slug无法自动生成,仅admin后台正常如何解决?
问题原因
- 你自定义的
PostForm默认将slug字段设为必填项,表单提交时如果slug为空会直接触发校验失败,不会执行模型层写的save()方法,自动生成逻辑无法触发。 - Django admin的实时填充slug效果是自带前端JS交互实现的,你自定义的发布页面没有对应JS逻辑,所以输入标题时不会实时生成slug内容。
解决方案
方案1:仅提交后自动生成slug(无需前端实时填充)
步骤1:调整表单配置
修改你的forms.py中的PostForm,将slug字段移出表单填写项,完全交给模型层自动生成,同时注意也不要把author字段放到表单让用户填写:
from django import forms from .models import Post class PostForm(forms.ModelForm): class Meta: model = Post # 只保留需要用户填写的字段 fields = ['title', 'title_type', 'content', 'status', 'image']
步骤2:完善视图逻辑
修改views.py中的AddPostView,自动给文章赋值当前登录用户为作者:
class AddPostView(CreateView): model = Post form_class = PostForm template_name = 'add_post.html' def form_valid(self, form): form.instance.author = self.request.user return super().form_valid(form)
如果需要支持用户自定义修改slug,不想直接移除字段,可以将slug设为非必填,同时调整模型的save方法,仅在slug为空时自动生成:
# models.py 中调整save方法 def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.title) super(Post, self).save(*args, **kwargs)
方案2:实现和admin一致的实时填充slug效果
在add_post.html模板中添加如下JS代码即可实现输入标题时自动生成slug:
document.addEventListener('DOMContentLoaded', function() { // Django自动生成的表单字段默认id为 id_字段名,如果你自定义了表单id请对应修改 const titleInput = document.getElementById('id_title'); const slugInput = document.getElementById('id_slug'); titleInput.addEventListener('input', function() { let slug = this.value.toLowerCase() // 移除非字母数字、空格、连字符的字符 .replace(/[^a-z0-9\s-]/g, '') // 空格替换为连字符 .replace(/\s+/g, '-') // 多个连续连字符合并为一个 .replace(/-+/g, '-'); slugInput.value = slug; }); });
额外注意
Django自带的slugify方法不支持中文,如果你需要处理中文标题生成拼音slug,可以安装pypinyin库后调整save方法的生成逻辑即可。
内容的提问来源于stack exchange,提问作者Dinindu Theekshana
相关产品推荐
相关产品推荐

