You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:26:19