有没有简单的方法从CharField填充SlugField?

时间:2008-09-26 19:40:58

标签: python django slug

class Foo(models.Model):
    title = models.CharField(max_length=20)
    slug = models.SlugField()

是否有内置的方法可以根据标题让slug字段自动填充?也许在管理员和管理员之外。

6 个答案:

答案 0 :(得分:61)

对于Django 1.0及更高版本的Admin,您需要使用

prepopulated_fields = {'slug': ('title',), }
你的admin.py

中的

您在prepopulated_fields字典中的键是您要填充的字段,该值是您想要连接的字段的元组。

在管理员之外,您可以在视图中使用slugify功能。在模板中,您可以使用|slugify过滤器。

此软件包还会自动处理此问题:https://pypi.python.org/pypi/django-autoslug

答案 1 :(得分:6)

在管理员之外,请参阅this django snippet。将它放在.save()中,它将与以编程方式创建的对象一起使用。在管理员内部,正如其他人所说,使用prepopulated_fields

答案 2 :(得分:3)

对于1.0之前的版本:

slug = models.SlugField(prepopulate_from=('title',))

应该可以正常工作

对于1.0,请使用camflan's

答案 3 :(得分:2)

您还可以使用pre_save django信号填充django管理代码之外的slug。 请参阅Django signals documentation

Ajax slug唯一性验证也很有用,请参阅As-You-Type Slug Uniqueness Validation @ Irrational Exuberance

答案 4 :(得分:0)

过去,{p> autoslug对我来说效果很好。虽然我从未尝试过使用管理员应用程序。

答案 5 :(得分:0)

我想添加一个完整且最新的答案,并提及问题:

1。在Django Admin中自动填充表单

如果您只关心在管理员中添加和更新数据,则只需使用prepopulated_fields属性

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}

admin.site.register(Article, ArticleAdmin)

2。在模板中自动填充自定义表单

如果您使用表单构建了服务器呈现的界面,则可以在保存表单(is_valid)时使用|slugify模板模板过滤器或slugify实用程序来自动填充字段。

3。使用django-autoslug在模型级别自动填充slugfields

上述解决方案仅在通过那些界面(管理员或自定义表单)操作数据时才自动填充slugfield(或任何字段)。如果您有API,管理命令或其他任何可以处理数据的内容,则需要下拉至模型级别。

django-autoslug提供了AutoSlugField字段,该字段扩展了SlugField,并允许您设置应该将其整齐地塞入的字段:

class Article(Model):
    title = CharField(max_length=200)
    slug = AutoSlugField(populate_from='title')

该字段使用pre_save和post_save信号来实现其功能,因此请参阅此答案底部的陷阱文本。

4。通过覆盖save()在模型级别自动填充slugfields

最后一个选项是自己实现,这涉及覆盖默认的save()方法:

    class Article(Model):
        title = CharField(max_length=200)
        slug = SlugField()

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Job, self).save(*args, **kwargs)

注意:批量更新将绕过您的代码(包括信号)

这是Django初学者的常见误解。首先,您应该知道pre_save和post_save信号与save()方法直接相关。其次,通过直接在SQL层上进行操作,Django中进行批量更新的不同方法都绕过了save()方法来实现高性能。这意味着对于以上解决方案3或4中使用的示例模型:

  • Article.objects.all()。update(title ='新帖子')将更新任何文章的内容
  • 在Article模型上使用bulk_createbulk_update更新任何文章的内容。
  • 由于未调用save()方法,因此将不会发出pre_save或post_save信号

要进行批量更新并仍然利用代码级约束,唯一的解决方案是逐个迭代对象并调用其save()方法,其性能大大低于SQL级批量操作。您当然可以在数据库中使用触发器,尽管那是完全不同的主题。