求助:Django项目地址栏无法显示slug字段问题
Django Slug字段未生效问题排查与修复
我是Django新手,在练习为模型添加slug字段时遇到问题——程序运行后slug字段未生效,且浏览器没有显示任何报错信息。以下是我的相关代码,请帮忙排查解决:
原代码文件
models.py
from django.db import models from django.db.models.signals import pre_save from django.dispatch import receiver from django.utils.text import slugify import string,random from temp1.util import unique_slug_generator STATUS_CHOICES = ( ('draft', 'Draft'), ('published', 'Published'), ) class Post(models.Model): title = models.CharField(max_length = 250) slug = models.SlugField(max_length = 250, null = True, blank = True) text = models.TextField() published_at = models.DateTimeField(auto_now_add = True) updated = models.DateTimeField(auto_now = True) status = models.CharField(max_length = 10, choices = STATUS_CHOICES, default ='draft') class Meta: ordering = ('-published_at', ) def __str__(self): return self.title @receiver(pre_save, sender=Post) def pre_save_receiver(sender, instance, *args, **kwargs): if not instance.slug: instance.slug = unique_slug_generator(instance)
urls.py
from django.urls import path from .views import detail urlpatterns = [ path("posts/",detail,name="home") ]
util.py
import string, random from django.db.models.signals import pre_save from django.dispatch import receiver from django.utils.text import slugify def random_string_generator(size = 10, chars = string.ascii_lowercase + string.digits): return ''.join(random.choice(chars) for _ in range(size)) def unique_slug_generator(instance, new_slug = None): if new_slug is not None: slug = new_slug else: slug = slugify(instance.title) Klass = instance.__class__ max_length = Klass._meta.get_field('slug').max_length slug = slug[:max_length] qs_exists = Klass.objects.filter(slug = slug).exists() if qs_exists: new_slug = "{slug}-{randstr}".format( slug = slug[:max_length-5], randstr = random_string_generator(size = 4)) return unique_slug_generator(instance, new_slug = new_slug) return slug
views.py
from django.http import HttpResponse from .models import Post def detail(request, slug=None): q = Post.objects.filter(slug__iexact = slug) if q.exists(): q = q.first() else: return HttpResponse("<h1>Post Not Found</h1>") context = { 'post': q } return render(request, 'posts/details.html', context)
details.html
<!DOCTYPE HTML> <HTML> <head> <meta charset="utf-8"> <title></title> </head> <body> <form method="POST"> {% csrf_token %} {{form.as_p}} <a href="/posts/{{ a.slug }}" class="btn btn- primary">View</a> <input type="submit" value="submit"> </form> </body> </html>
问题排查与修复
1. util.py 生成器函数逻辑错误
原unique_slug_generator函数中,递归调用的return语句不在if qs_exists代码块内,导致无论slug是否重复都会触发无限递归,无法正常返回slug值。
修正后的代码:
def unique_slug_generator(instance, new_slug = None): if new_slug is not None: slug = new_slug else: slug = slugify(instance.title) Klass = instance.__class__ max_length = Klass._meta.get_field('slug').max_length slug = slug[:max_length] qs_exists = Klass.objects.filter(slug = slug).exists() if qs_exists: new_slug = "{slug}-{randstr}".format( slug = slug[:max_length-5], randstr = random_string_generator(size = 4) ) return unique_slug_generator(instance, new_slug=new_slug) return slug
2. models.py 类内部缩进错误
原代码中class Meta与Post类同级,导致Django无法识别模型的排序配置,需将Meta类缩进至Post类内部:
修正后的片段:
class Post(models.Model): title = models.CharField(max_length = 250) slug = models.SlugField(max_length = 250, null = True, blank = True) text = models.TextField() published_at = models.DateTimeField(auto_now_add = True) updated = models.DateTimeField(auto_now = True) status = models.CharField(max_length = 10, choices = STATUS_CHOICES, default ='draft') class Meta: ordering = ('-published_at', ) def __str__(self): return self.title
3. urls.py 未配置slug参数路径
原URL路径未接收slug参数,导致视图无法获取slug值进行查询,需修改路径格式:
修正后的代码:
from django.urls import path from .views import detail urlpatterns = [ path("posts/<slug:slug>/", detail, name="post-detail"), ]
4. views.py 缺失必要导入与表单逻辑
原视图未导入render函数,且未处理表单提交逻辑,导致模板无法正常创建Post对象:
修正后的代码(需配合创建PostForm表单类):
from django.http import HttpResponse from django.shortcuts import render from .models import Post from .forms import PostForm def detail(request, slug=None): # 处理表单提交 if request.method == "POST": form = PostForm(request.POST) if form.is_valid(): form.save() return HttpResponse("<h1>文章创建成功!</h1>") else: form = PostForm() # 处理slug查询 if slug: post = Post.objects.filter(slug__iexact=slug).first() if not post: return HttpResponse("<h1>未找到该文章</h1>") context = {'post': post, 'form': form} else: posts = Post.objects.all() context = {'posts': posts, 'form': form} return render(request, 'posts/details.html', context)
配套forms.py代码:
from django import forms from .models import Post class PostForm(forms.ModelForm): class Meta: model = Post fields = ['title', 'text', 'status']
5. details.html 模板变量错误
原模板使用错误的变量{{ a.slug }},需替换为视图传递的post变量,同时修正链接路径:
修正后的片段:
<form method="POST"> {% csrf_token %} {{form.as_p}} {% if post %} <a href="/posts/{{ post.slug }}" class="btn btn-primary">查看文章</a> {% endif %} <input type="submit" value="提交"> </form> {% if post %} <h2>{{ post.title }}</h2> <p>{{ post.text }}</p> {% endif %}
最后步骤:更新数据库结构
修改模型后,执行以下命令更新数据库:
python manage.py makemigrations python manage.py migrate
内容的提问来源于stack exchange,提问作者Dhani
相关产品推荐
相关产品推荐

