Почему 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/

есть три вещи, которые заставляют меня принять этот метод

  1. поле Slug не имеет неявной уникальности.
  2. get_object_or_404(Blog, pk=id) должен быть быстрее, чем get_object_or_404(Blog, slug=slug).
  3. добавление поля slug к существующим моделям включает миграцию данных.

так почему SlugField ()? , помимо стоимости динамически генерирующего слизня, каковы недостатки вышеуказанного метода ?

2 ответов


почему SlugField () в Django? Потому что:

  1. это человек дружелюбный (например. /блог/ вместо /1/).
  2. это хорошо 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