【问题标题】:Is there an easy way to populate SlugField from CharField?有没有一种简单的方法可以从 CharField 填充 SlugField?
【发布时间】:2010-09-13 13:53:12
【问题描述】:
class Foo(models.Model):
    title = models.CharField(max_length=20)
    slug = models.SlugField()

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

【问题讨论】:

    标签: python django slug


    【解决方案1】:

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

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

    在你的 admin.py 中

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

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

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

    【解决方案2】:

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

    【讨论】:

    • 我同意,但要注意批量插入... save() 方法不是直接调用的。
    【解决方案3】:

    对于 1.0 之前的版本:

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

    应该没问题

    对于 1.0,请使用 camflan's

    【讨论】:

      【解决方案4】:

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

      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-fields,它扩展了 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() 方法直接相关。其次,在 Django 中进行批量更新的不同方法都通过直接在 SQL 层上操作来绕过 save() 方法来实现高性能。这意味着对于上述解决方案 3 或 4 中使用的示例模型:

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

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

      【讨论】:

        【解决方案5】:

        您还可以使用 pre_save django 信号在 django 管理代码之外填充 slug。 见Django signals documentation

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

        【讨论】:

        • 我想知道这种方法是否适用于批量插入?我不确定:/
        • 您必须为批量操作制定解决方法,您可以查看此线程以获取一些见解stackoverflow.com/questions/23744795/…
        【解决方案6】:

        autoslug 过去对我来说效果很好。虽然我从未尝试将它与管理应用程序一起使用。

        【讨论】:

          猜你喜欢
          • 2011-06-03
          • 2014-12-08
          • 1970-01-01
          • 2010-12-12
          • 2021-09-18
          • 2013-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多