Почему SlugField() в Джанго?
Django есть models.SlugField()
что помогает нам создавать некоторые интересные URL-адреса.
Мой вопрос в том, зачем указывать его как поле
предположим, у меня есть это модель
class Blog(models.Model):
title = models.CharField()
и если я хочу добавить слизняк, я мог бы просто использовать
class Blog(models.Model):
title = models.CharField()
def title_slug(self):
return slugify(self.title)
на urls я мог бы просто использовать
(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)
...
urls будет выглядеть как
example.com/blog/23/why-iam-here/
есть три вещи, которые заставляют меня принять этот метод
- поле Slug не имеет неявной уникальности.
-
get_object_or_404(Blog, pk=id)
должен быть быстрее, чемget_object_or_404(Blog, slug=slug)
. - добавление поля slug к существующим моделям включает миграцию данных.
так почему SlugField ()? , помимо стоимости динамически генерирующего слизня, каковы недостатки вышеуказанного метода ?
2 ответов
почему SlugField () в Django? Потому что:
- это человек дружелюбный (например. /блог/ вместо /1/).
- это хорошо SEO для создания согласованности в названии, заголовке и URL.
большой недостаток вашего динамически генерируемого слизняка, принимающего слизняки в urls.py и не использовать пулю, чтобы получить нужный объект? Это плохой дизайн.
Если вы предоставляете и принимаете слизни, но не проверяете их, то у вас есть несколько URL-адресов, возвращающих тот же контент. Так что /1/полезно-slug/ и / 1 / this-is-a-bs-slug/ оба вернут одну и ту же страницу.
это плохо, потому что это не делает жизнь проще для людей. Ваши посетители должны предоставить идентификатор и что-то, что является избыточным. Дублированные страницы-кошмар поисковых систем. Какая страница правильная? Дублированные страницы будут иметь низкий ранг. См.https://support.google.com/webmasters/answer/40349?hl=en (последний p)
вы можете утверждать, что вы последовательно реализуете свои собственные красиво сгенерированные ссылки, но люди и боты все время угадывают URL-адреса (см. ваши файлы журналов). Когда вы принимаете все слизни, люди и боты всегда угадывают правильно.
также сохранение пули в БД экономит вычислительную мощность. Вы создаете слизняк один раз и повторно его используете. Что будет более (в)эффективно искать слизень или генерировать его каждый раз?
поля Slug в admin полезны для предоставления Редакторы возможность редактировать slug. Возможно, чтобы предоставить дополнительную информацию, которая не находится в названии, но все же стоит упомянуть.
Bonus: обновить перенесенные данные:
from django.template.defaultfilters import slugify
for obj in Blog.objects.filter(slug=""):
obj.slug = slugify(obj.title)
obj.save()
поле Slug не имеет неявной уникальности.
нет неявной уникальности с CharField
. Вам нужно указать unique=True
если вы хотите убедиться, что каждая строка уникальна на уровне БД. Вы должны сделать это с CharField
и SlugField
Так что никаких преимуществ для любого
get_object_or_404(Blog, pk=id) должен быть быстрее, чем get_object_or_404 (Blog, slug=slug).
там может быть, очень небольшая разница из-за индекса на вашем первичном ключе, но это, вероятно, незначительно. Это не имеет ничего общего с помощью CharField
vs SlugField
хотя-вы только что создали другой URL, который принимает id
и используют это для поиска.
добавление поля slug к существующим моделям включает миграцию данных.
добавлять CharField
для существующей модели также требуется миграция данных, поэтому здесь нет никаких преимуществ.
SlugFields
просто CharField
с дополнительной проверкой. код. Ты нарушаешь золотое правило Джанго-не повторяйся.
кроме того, если вы просто использовать CharField
вы не получаете никакой проверки на уровне формы, поэтому вы можете очень легко создать "слизень", который не соответствует проверке слизняков, т. е. у него могут быть пробелы или символы, которые не разрешены в URL.
и с этого подход, если вы измените свое название, URL-адрес изменился и теперь все старые ссылки мертвы. Наличие слизнякового поля предотвращает это.
Вы делаете больше проблем для себя здесь - просто используйте SlugField