我目前正在Django开展一个玩具项目。
我的部分应用允许用户留下评论。我想获取评论的标题并将其强化以创建一个网址。
因此,如果用户写了一篇名为“有史以来最好的东西!”的评论,那么网址就像:www.example.com/reviews/the-best-thing-ever
。
这一切都很好,但处理两个用户选择相同标题的情况的最佳方法是什么?我不想让标题必须是唯一的。
我已经考虑过在某个网址添加评论ID,但我想避免任何不会发生碰撞的网址的额外信息。
有什么想法吗?
答案 0 :(得分:6)
我会推荐类似AutoSlugField的内容。它有一些关于配置唯一性的选项(unique
和unique_with
),并且还有一个额外的好处,即如果您愿意,可以根据模型上的其他字段自动生成slug。
答案 1 :(得分:6)
我从不喜欢独特的slug字段/方法的一件事是,如果你对一个标题有很多冲突,你最终会运行几个查询来尝试确定一个可用的slug。我知道你提到你不想显示非冲突slu的id,但是,就性能而言,我认为这是更好的选择。为了使URL更好看,我更喜欢在slug之前嵌入id,以便URL采用www.example.com/reviews/1/the-best-thing-ever的形式。
答案 2 :(得分: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
当然会更改相应的名称和表单定义,但您明白了这一点:)
答案 3 :(得分:0)
我会(在表单验证中)只是检查是否使用了slug,然后添加一些东西,或者是一个数字“my-cool-idea_2”或实际的id