Почему SlugField() в Django?
Django имеет models.SlugField()
, который помогает нам создавать интересные URL-адреса.
Мой вопрос в том, почему его указать как поле
предположим, что у меня есть эта модель
class Blog(models.Model):
title = models.CharField()
и если я хочу добавить slug, я мог бы просто использовать
class Blog(models.Model):
title = models.CharField()
def title_slug(self):
return slugify(self.title)
в URL Я мог бы просто использовать
(r'^blog/(?P<id>\d+)/(?P<slug>[-\w]+)/$', 'app.views.blog_view'),
и в представления
def blog_view(request, id ,slug):
get_object_or_404(Blog, pk=id)
...
URL-адреса будут выглядеть как
example.com/blog/23/why-iam-here/
Есть три вещи, которые заставляют меня принять этот метод
- Поле слияния не приходит с неявной уникальностью.
-
get_object_or_404(Blog, pk=id)
должен быть быстрее, чем get_object_or_404(Blog, slug=slug)
.
- Добавление поля slug к существующим моделям включает перенос данных.
так почему SlugField()?, кроме затрат на динамическое создание пули, каковы недостатки вышеуказанного метода?
Ответы
Ответ 1
Почему SlugField() в Django? Потому что:
- это дружелюбный человек (например./blog/вместо/1/).
- Хороший SEO для создания согласованности в заголовке, заголовке и URL-адресе.
Большой недостаток вашего динамически сгенерированного слизня, принятие пули в urls.py и не использование пули для получения правильного объекта? Это плохой дизайн.
Если вы поставляете и принимаете пули, но не проверяете их, тогда у вас есть несколько URL-адресов, возвращающих один и тот же контент. Таким образом, /1/полезный-slug/ и /1/this-is-b-slug/ будут возвращать одну и ту же страницу.
Это плохо, потому что это не делает жизнь легкой для людей. Ваши посетители должны предоставить идентификатор и что-то лишнее. Дублированные страницы - кошмар поисковых систем. Какая страница является правильной? Дублированные страницы получат низкий ранг. См. https://support.google.com/webmasters/answer/40349?hl=en (последний p)
Вы можете утверждать, что постоянно реализуете свои собственные прекрасно созданные ссылки, но люди и боты все время угадывают URL-адреса (см. ваши лог файлы). Когда вы принимаете все слизняки, люди и боты всегда догадываются правильно.
Также сохранение пули в db сохраняет вычислительную мощность. Вы генерируете slug один раз и повторно используете его. Что будет больше (в) эффективном поиске пули или генерации его каждый раз?
Сливные поля в admin полезны, чтобы дать редакторам возможность редактировать пули. Возможно, чтобы предоставить дополнительную информацию, которая отсутствует в названии, но все же стоит упомянуть.
Бонус: обновление перенесенных данных:
from django.template.defaultfilters import slugify
for obj in Blog.objects.filter(slug=""):
obj.slug = slugify(obj.title)
obj.save()
Ответ 2
Поле слияния не приходит с неявной уникальностью.
Нет однозначной уникальности с CharField
. Вам нужно указать unique=True
, если вы хотите, чтобы каждая строка была уникальной на уровне БД. Вы должны сделать это как с помощью CharField
, так и SlugField
, чтобы не было преимуществ для
get_object_or_404 (Блог, pk = id) должен быть быстрее, чем get_object_or_404 (Блог, slug = slug).
Может быть очень небольшое различие из-за индекса вашего первичного ключа, но это, вероятно, незначительно. Это не имеет никакого отношения к использованию CharField
vs SlugField
, хотя - вы только что создали другой URL-адрес, который принимает id
и использует это для поиска.
Добавление поля slug к существующим моделям включает перенос данных.
Добавление CharField
к существующей модели также потребовало переноса данных, поэтому здесь нет никакого преимущества.
SlugFields
просто CharField
с дополнительным битом проверки. Посмотрите на код. Вы нарушаете золотое правило Django DRY - не повторяйте себя.
Кроме того, если вы просто используете CharField
, вы не получаете никакой проверки на уровне формы, поэтому вы можете очень легко создать "slug", который не соответствует проверке пули, т.е. может иметь место или символы, которые не разрешены в URL-адресе.
Также с этим подходом, если вы измените название, ваш URL изменился, и теперь все ваши старые ссылки мертвы. Наличие поля пули предотвращает это.
У вас больше проблем для себя здесь - просто используйте SlugField