Есть ли простой способ заполнить SlugField из CharField?
Вопрос
class Foo(models.Model):
title = models.CharField(max_length=20)
slug = models.SlugField()
Есть ли встроенный способ заставить поле slug автоматически заполняться на основе заголовка?Возможно, в Админке и за ее пределами.
Решение
для администрирования в Django 1.0 и выше вам нужно будет использовать
prepopulated_fields = {'slug': ('title',), }
в вашем admin.py
Ваш ключ в словаре prepopulated_fields - это поле, которое вы хотите заполнить, а значение - это кортеж полей, которые вы хотите объединить.
За пределами admin вы можете использовать slugify
функционируйте в ваших представлениях.В шаблонах вы можете использовать |slugify
Фильтр.
Существует также этот пакет, который позаботится об этом автоматически: https://pypi.python.org/pypi/django-autoslug
Другие советы
За пределами администратора смотрите этот фрагмент django.Положи это в свой .save()
, и это будет работать с объектами, созданными программно.Внутри администратора, как уже говорили другие, используйте prepopulated_fields
.
Для версии до версии 1.0:
slug = models.SlugField(prepopulate_from=('title',))
должно сработать просто отлично
Для версии 1.0 используйте камфланский
Вы также можете использовать pre_save django signal для заполнения slug вне кода администратора django.Видишь Документация по сигналам Django.
Проверка уникальности Ajax slug также будет полезна, см. Проверка уникальности Слага по мере ввода @ Иррациональное изобилие
автослюнявчик в прошлом это работало у меня довольно хорошо.Хотя я никогда не пробовал использовать его с приложением admin.
Подумал, что хотел бы добавить полный и актуальный ответ с упомянутыми ошибками:
1.Автоматическое заполнение форм в Django Admin
Если вас интересует только добавление и обновление данных в admin, вы могли бы просто использовать предварительно заполненные поля атрибут
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
admin.site.register(Article, ArticleAdmin)
2.Автоматическое заполнение пользовательских форм в шаблонах
Если вы создали свой собственный серверный интерфейс с формами, вы могли бы автоматически заполнять поля, используя либо |слизнуть накладной фильтр или слизывать утилита при сохранении формы (is_valid).
3.Автоматическое заполнение полей slugfields на уровне модели с помощью django-autoslug
Вышеупомянутые решения будут автоматически заполнять slugfield (или любое другое поле) только тогда, когда данные обрабатываются через эти интерфейсы (администратор или пользовательская форма).Если у вас есть API, команды управления или что-то еще, что также манипулирует данными, вам нужно перейти на уровень модели.
django-автоматический сервис предоставляет AutoSlugField-поля, которые расширяют SlugField и позволяют вам установить, какое поле оно должно аккуратно заполнять:
class Article(Model):
title = CharField(max_length=200)
slug = AutoSlugField(populate_from='title')
Поле использует сигналы pre_save и post_save для достижения своей функциональности, поэтому, пожалуйста, ознакомьтесь с текстом gotcha в нижней части этого ответа.
4.Автоматическое заполнение полей slugfields на уровне модели путем переопределения функции save()
Последний вариант - реализовать это самостоятельно, что предполагает переопределение метода 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 обходят метод save() для достижения высокой производительности, работая непосредственно на SQL-уровне.Это означает, что для примера модели, используемой в решении 3 или 4 выше:
- Article.objects.all().update(заголовок='Новое сообщение') будет НЕТ обновите заголовок любой статьи
- Используя bulk_create - создать или объемное обновление на модели статьи будет НЕТ обновите заголовок любой статьи.
- Поскольку метод save()-не вызывается, сигналы pre_save или post_save отправляться не будут.
Чтобы выполнять массовые обновления и по-прежнему использовать ограничения на уровне кода, единственным решением является повторение объектов один за другим и вызов его метода save(), который имеет значительно меньшую производительность, чем массовые операции на уровне SQL.Конечно, вы могли бы использовать триггеры в своей базе данных, хотя это совершенно другая тема.