Django slug化URL - 如何处理冲突?
我现在正在做一个小项目,使用的是Django这个框架。
我的应用程序有一个功能,允许用户留下评论。我想把评论的标题进行处理,生成一个网址。
比如,如果用户写的评论标题是“最棒的东西!”,那么生成的网址就会像这样:www.example.com/reviews/the-best-thing-ever
。
这听起来不错,但如果有两个用户都选择了相同的标题,该怎么处理呢?我不想强制要求标题必须是唯一的。
我考虑过在网址中加上评论的ID,但我希望对于那些没有冲突的网址来说,能避免多余的信息。
有没有什么好主意呢?
4 个回答
2
from django.template.defaultfilters import slugify
def slugify_unique(value, model, slugfield="slug"):
suffix = 0
potential = base = slugify(value)
while True:
if suffix:
potential = "-".join([base, str(suffix)])
if not model.objects.filter(**{slugfield: potential}).count():
return potential
suffix += 1
"""
above function is not my code, but i don't remember exactly where it comes from
you can find many snippets with such solutions searching for 'unique slug' and so
"""
class ReviewForm(forms.ModelForm):
def save(self, user, commit=True):
self.instance.slug = slugify_unique(self.cleaned_data['title'], self.Meta.model)
review = super(ReviewForm, self).save(commit)
review.save()
return review
class Meta:
model = Review
当然要更改合适的名称和表单定义,不过你明白我的意思了 :)
6
我建议你可以试试 AutoSlugField。这个工具有一些选项可以让你设置唯一性(比如 unique
和 unique_with
),而且它还有一个额外的好处,就是可以根据你模型中的其他字段自动生成“slug”(一种简短的、易于阅读的文本标识),如果你需要的话。
6
我一直不太喜欢那种独特的slug字段或方法,因为如果你有很多相同标题的冲突,你就得跑好几次查询来找一个可用的slug。我知道你提到过不想在没有冲突的slug中显示ID,但从性能的角度来看,我觉得显示ID会更好。为了让网址看起来更好,我更喜欢在slug前面加上ID,这样网址就会变成 www.example.com/reviews/1/the-best-thing-ever。