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

发布于 2024-07-05 12:14:07 字数 173 浏览 8 评论 0 原文

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

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

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

Is there a built-in way to get the slug field to autopopulate based on the title? Perhaps in the Admin and outside of the Admin.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

深者入戏 2024-07-12 12:14:07

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

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

在 admin.py 中

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

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

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

for Admin in Django 1.0 and up, you'd need to use

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

in your admin.py

Your key in the prepopulated_fields dictionary is the field you want filled, and the value is a tuple of fields you want concatenated.

Outside of admin, you can use the slugify function in your views. In templates, you can use the |slugify filter.

There is also this package which will take care of this automatically: https://pypi.python.org/pypi/django-autoslug

欢你一世 2024-07-12 12:14:07

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

1. 在 Django 管理中自动填充表单

如果您只关心在管理中添加和更新数据,您可以简单地使用 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 提供了 AutoSlugField-fields ,它扩展了 SlugField 并允许您设置它的字段应该整齐地 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 中使用的示例模型:

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

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

Thought I would add a complete and up-to-date answer with gotchas mentioned:

1. Auto-populate forms in Django Admin

If you are only concerned about adding and updating data in the admin, you could simply use the prepopulated_fields attribute

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

admin.site.register(Article, ArticleAdmin)

2. Auto-populate custom forms in templates

If you have built your own server-rendered interface with forms, you could auto-populate the fields by using either the |slugify tamplate filter or the slugify utility when saving the form (is_valid).

3. Auto-populating slugfields at model-level with django-autoslug

The above solutions will only auto-populate the slugfield (or any field) when data is manipulated through those interfaces (the admin or a custom form). If you have an API, management commands or anything else that also manipulates the data you need to drop down to model-level.

django-autoslug provides the AutoSlugField-fields which extends SlugField and allows you to set which field it should slugify neatly:

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

The field uses pre_save and post_save signals to achieve its functionality so please see the gotcha text at the bottom of this answer.

4. Auto-populating slugfields at model-level by overriding save()

The last option is to implement this yourself, which involves overriding the default save() method:

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

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

NOTE: Bulk-updates will bypass your code (including signals)

This is a common miss-understanding by beginners to Django. First you should know that the pre_save and post_save signals are directly related to the save()-method. Secondly the different ways to do bulk-updates in Django all circumvent the save()-method to achieve high performance, by operating directly on the SQL-layer. This means that for the example model used in solution 3 or 4 above:

  • Article.objects.all().update(title='New post') will NOT update the slug of any article
  • Using bulk_create or bulk_update on the Article model will NOT update the slug of any article.
  • Since the save()-method is not called, no pre_save or post_save signals will be emitted.

To do bulk updates and still utilize code-level constraints the only solution is to iterate objects one by one and call its save()-method, which has drastically less performance than SQL-level bulk operations. You could of course use triggers in your database, though that is a totally different topic.

无人问我粥可暖 2024-07-12 12:14:07

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

autoslug has worked quite well for me in the past. Although I've never tried using it with the admin app.

笑梦风尘 2024-07-12 12:14:07

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

Ajax slug 唯一性验证也很有用,请参阅 即用型 Slug 唯一性验证@非理性繁荣

You can also use pre_save django signal to populate slug outside of django admin code.
See Django signals documentation.

Ajax slug uniqueness validation will be useful too, see As-You-Type Slug Uniqueness Validation @ Irrational Exuberance

温柔戏命师 2024-07-12 12:14:07
prepopulated_fields = {'slug': ('title',), }
prepopulated_fields = {'slug': ('title',), }
云归处 2024-07-12 12:14:07

使用内置的 django slugify 在模型级别自动填充 slugfield:

models.py

from django.db import models


class Place:
    name = models.CharField(max_length=50)
    slug_name = models.SlugField(max_length=50)

signals.py

from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.template.defaultfilters import slugify as django_slugify

from v1 import models


@receiver(pre_save, sender=models.Place)
def validate_slug_name(sender, instance: models.Place, **kwargs):
    instance.slug_name = django_slugify(instance.name)

来源:https://github.com/justinmayer/django-autoslug/blob/ 9e3992296544a4fd7417a833a9866112021daa82/autoslug/utils.py#L18

Auto-populating slugfields at model-level with the built-in django slugify:

models.py

from django.db import models


class Place:
    name = models.CharField(max_length=50)
    slug_name = models.SlugField(max_length=50)

signals.py

from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.template.defaultfilters import slugify as django_slugify

from v1 import models


@receiver(pre_save, sender=models.Place)
def validate_slug_name(sender, instance: models.Place, **kwargs):
    instance.slug_name = django_slugify(instance.name)

Credits to: https://github.com/justinmayer/django-autoslug/blob/9e3992296544a4fd7417a833a9866112021daa82/autoslug/utils.py#L18

能怎样 2024-07-12 12:14:07

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

Outside the admin, see this django snippet. Put it in your .save(), and it'll work with objects created programmatically. Inside the admin, as the others have said, use prepopulated_fields.

遥远的绿洲 2024-07-12 12:14:07

对于 1.0 之前的版本:

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

应该可以正常工作

对于 1.0,请使用 卡姆弗兰的

For pre-1.0:

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

should work just fine

For 1.0, use camflan's

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文