有没有一种简单的方法可以从 CharField 填充 SlugField?

新手上路,请多包涵
class Foo(models.Model):
    title = models.CharField(max_length=20)
    slug = models.SlugField()

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

原文由 ashchristopher 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 413
2 个回答

对于 Django 1.0 及更高版本中的管理员,您需要使用

prepopulated_fields = {'slug': ('title',), }

在你的 admin.py

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

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

还有这个包会自动处理这个问题: https ://pypi.python.org/pypi/django-autoslug

原文由 camflan 发布,翻译遵循 CC BY-SA 3.0 许可协议

以为我会添加一个完整和最新的答案,其中提到了陷阱:

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

如果您只关心在管理员中添加和更新数据,您可以简单地使用 prepopulated_fields 属性

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

admin.site.register(Article, ArticleAdmin)

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

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

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

当通过这些界面(管理或自定义表单)操作数据时,上述解决方案只会自动填充 slugfield(或任何字段)。如果您有一个 API、管理命令或任何其他也可以操作数据的东西,您需要将其降到模型级别。

django-autoslug 提供了扩展 SlugField 的 AutoSlugField-fields 并允许您设置它应该整洁地 slugify 的字段:

 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().save(*args, **kwargs)

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

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

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

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

原文由 Andreas Bergström 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题