Django中如何实现基于创建时间的唯一Slug?
实现Slug结合创建时间唯一的方案
1. 修改Article模型
首先移除slug字段的unique=True,添加创建时间字段,并设置slug + 创建日期的联合唯一约束,以此保证同一slug在同一天内仅能存在一篇文章:
from django.db import models from django.utils.text import slugify from django.utils.timezone import now class Article(models.Model): title = models.CharField(max_length=200) description = models.TextField(blank=True, null=True) # 移除自身的unique约束,改用联合约束 slug = models.SlugField() user = models.ForeignKey('userauths.User', on_delete=models.SET_NULL, null=True) # 自动记录文章创建时间 created_at = models.DateTimeField(auto_now_add=True) class Meta: # 联合唯一约束:slug + 创建日期的组合唯一 unique_together = ('slug', models.Func('created_at', function='DATE'))
2. 自动生成无冲突的Slug
如果希望提交相同标题时自动生成带后缀的slug(避免手动修改),可以重写模型的save()方法,自动检测冲突并追加数字后缀:
def save(self, *args, **kwargs): # 仅在新建文章且未设置slug时自动生成 if not self.slug and self.title: base_slug = slugify(self.title) self.slug = base_slug # 获取当前日期(未保存时用当前时间) target_date = self.created_at.date() if self.created_at else now().date() counter = 1 # 检查slug+日期的组合是否已存在 while Article.objects.filter(slug=self.slug, created_at__date=target_date).exists(): self.slug = f"{base_slug}-{counter}" counter += 1 super().save(*args, **kwargs)
可选调整
- 如果需要更精确的唯一粒度(比如同一秒内仅一篇),可以把
unique_together里的models.Func('created_at', function='DATE')替换成created_at。 - 也可以把后缀改成时间戳(如
f"{base_slug}-{int(now().timestamp())}"),进一步降低冲突概率。
内容的提问来源于stack exchange,提问作者Destiny Franks
相关产品推荐
相关产品推荐

