Рубрики
Без рубрики

Джанго Слаг

В этом уроке мы добавим слизняков на веб -сайт Django. Как отмечалось в официальных документах: «Слинь – это новый … Помечено с Джанго, Питоном, Учебником, Новичками.

В этом уроке мы добавим слизняков на веб -сайт Django. Как отмечено в Официальные документы : «Слинька – это газетный термин. Slug – это короткая ярлыка для чего -то, содержащий только буквы, цифры, подчеркивание или дефисы. Они обычно используются в URL. “

Чтобы привести конкретный пример, предположим, что у вас есть газетный веб -сайт (например, мы построим в этом уроке). Для истории под названием «Привет, мир», URL будет Пример.com/hello-world Предполагая, что сайт назывался Пример.com Анкет

Несмотря на их повсеместное распространение, слизняки могут быть несколько сложными для реализации в первый раз, по крайней мере, по моему опыту. Поэтому мы будем реализовать все с нуля, чтобы вы могли видеть, как все части сочетаются друг с другом. Если вам уже удобно реализовать ListView и DefitailView, вы можете перейти прямо в раздел Slug.

Полный исходный код можно найти на GitHub Анкет

Настраивать

Чтобы начать, давайте перейдем в каталог для нашего кода. Это может быть размещено в любом месте на вашем компьютере, но если вы находитесь на Mac, простое местоположение-это Настольный компьютер Анкет

$ cd ~/Desktop
$ mkdir newspaper && cd newspaper

Чтобы отдать дань уважения Происхождение Джанго в газете , мы создадим базовый Газета Веб -сайт с статьями. Если вам нужна помощь в установке Python, Django и всех остальных ( См. Здесь для подробных инструкций ).

В вашей командной строке введите следующие команды, чтобы установить последнюю версию с Pipenv , Создайте проект под названием конфигурация , настроить начальную базу данных через мигрировать , а затем запустите локальный веб -сервер с Runserver Анкет

$ pipenv install django~=3.0.0
$ pipenv shell
(newspaper) $ django-admin startproject config .
(newspaper) $ python manage.py migrate
(newspaper) $ python manage.py runserver

Не забудьте включить этот период . В конце StartProject Команда! Это дополнительный шаг, который избегает Джанго создавать дополнительный каталог в противном случае.

Перейдите к http://127.0.0.1:8000/ В вашем веб -браузере, чтобы увидеть страницу приветствия Django, которая подтверждает, что все настроено правильно.

Статьи приложение

Поскольку в центре внимания этого учебника сосредоточено на слизняках, я просто собираюсь дать команды и код, чтобы подключить это приложение статьи. Полные объяснения можно найти в моей книге Джанго для начинающих !

Начнем с создания приложения под названием Статьи Анкет Остановить локальный сервер с Контроль+c и используйте StartApp команда для создания этого нового приложения.

(newspaper) $ python manage.py startapp articles

Тогда обновление Insted_apps В нашем config/settings.py Файл, чтобы уведомить Джанго о приложении.

# config/settings.py
INSTALLED_APPS = [
    ...
    'articles.apps.ArticlesConfig', # new
]

Статья модель

Создайте модель базы данных, которая будет иметь Название и тело Анкет Мы также установим __str__ и get_absolute_url которые являются лучшими практиками Джанго.

# articles/models.py
from django.db import models
from django.urls import reverse

class Article(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('article_detail', args=[str(self.id)])

Теперь создайте файл миграции для этого изменения, затем добавьте его в нашу базу данных через мигрировать Анкет

(newspaper) $ python manage.py makemigrations articles
(newspaper) $ python manage.py migrate

Джанго администратор

Администратор Django – это удобный способ поиграть с моделями, поэтому мы его будем использовать. Но сначала создайте учетную запись суперпользователя.

(newspaper) $ python manage.py createsuperuser

А затем обновление Статьи/admin.py Чтобы отобразить наше приложение в администраторе.

# articles/admin.py
from django.contrib import admin

from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'body',)

admin.site.register(Article, ArticleAdmin)

Запустите сервер снова с Python Manage.py Runserver и перейдите к администратору в http://127.0.0.1:8000/admin . Войдите в систему с учетной записью суперпользователя.

Нажмите на «+ добавить» рядом с Статьи раздел и добавьте запись.

URL

В дополнение к модели, нам в конечном итоге понадобится URL, просмотр и шаблон для отображения страницы статьи. Мне нравится переходить на URL -адреса следующих после моделей, хотя заказ не имеет значения: нам нужны все четыре, прежде чем мы сможем отобразить одну страницу. Первый шаг – добавить Статьи Приложение на нашем уровне проекта config/urls.py файл.

# config/urls.py
from django.contrib import admin
from django.urls import path, include # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('articles.urls')), # new
]

Далее мы должны создать уровень приложения urls.py файл.

$ touch articles/urls.py

У нас будет ListView перечислить все статьи и DetailView Для отдельных статей.

Обратите внимание, что мы ссылаемся на два представления, которые еще не созданы: ArticleListView и ArticledetailView Анкет Мы добавим их в следующем разделе.

# articles/urls.py
from django.urls import path

from .views import ArticleListView, ArticleDetailView

urlpatterns = [
    path('', ArticleDetailView.as_view(), name='article_detail'),
    path('', ArticleListView.as_view(), name='article_list'),
]

Просмотры

Для каждого представления мы указываем соответствующую модель и соответствующий еще не созданный шаблон.

# articles/views.py
from django.views.generic import ListView, DetailView

from .models import Article

class ArticleListView(ListView):
    model = Article
    template_name = 'article_list.html'


class ArticleDetailView(DetailView):
    model = Article
    template_name = 'article_detail.html'

Шаблоны

Наконец, мы подходим к последнему шагу: шаблоны. По умолчанию Django будет смотреть в каждом приложении для Шаблоны каталог. Эта структура в нашем случае будет Статьи/шаблоны/шаблон.html .

Тип Контроль+c В командной строке и создайте новый шаблоны каталог.

(newspaper) $ mkdir articles/templates

Теперь добавьте два новых шаблона.

(newspaper) $ touch articles/templates/article_list.html
(newspaper) $ touch articles/templates/article_detail.html

Для нашей страницы списка мы переоцениваем Object_list который обеспечивается Посмотреть список . И добавляем a href с помощью get_absolute_url Метод добавлен в модель.


Articles

{% for article in object_list %} {% endfor %}

Вид с подробным представлением выводит два наших полях- заглавие и тело -Использование объект по умолчанию, предоставленное DefitailView. Вы можете и, вероятно, должны переименовать оба Object_list В ListView и объект в деталях быть более описательным.


{{ object.title }}

{{ object.body }}

Убедитесь, что сервер работает- Python Manage.py Runserver -И проверьте обе наши страницы в вашем веб-браузере.

Список всех статей доступен в http://127.0.0.1:8000/ Анкет

И подробный представление для нашей единственной статьи находится в http://127.0.0.1:8000/1 Анкет

Слизняки

Наконец мы приходим к слизнякам. В конечном итоге мы хотим, чтобы название нашей статьи было отражено в URL. Другими словами, «день в жизни» должен иметь URL http://127.0.0.1:8000/a-day-in-the-life Анкет

Требуется только два шага: обновление нашего Статьи/Models.py Файл и Статьи/urls.py Анкет Готовый? Пойдем…

В нашей модели мы можем добавить встроенный Джанго Slugfield Анкет Но мы должны также -и это та часть, которая обычно снимает людей с повышением кнопки get_absolute_url также. Вот где мы передаем значение, используемое в нашем URL. В настоящее время он проходит в id Для статьи и args , так 1 Для нашей первой статьи. Нам нужно изменить это на аргумент ключевого слова, Kwargs , для нашего слизняк Анкет

# articles/models.py
from django.db import models
from django.urls import reverse


class Article(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    slug = models.SlugField() # new

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('article_detail', kwargs={'slug': self.slug}) # new

Переезд давайте добавим файл миграции с тех пор, как мы обновили нашу модель.

(newspaper) $ python manage.py makemigrations articles
You are trying to add a non-nullable field 'slug' to article without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py

Ак! Что это?! Оказывается, мы уже Имейте данные в нашей базе данных, наша единственная статья, поэтому мы не можем просто добавить новое поле. Джанго помогает нам сказать, что нам либо нужно одноразовое по умолчанию NULL Или добавьте это сами. Хм.

По этой причине, как правило, хороший совет всегда добавлять новые поля с любым null = Верно или с по умолчанию ценность.

Давайте примем легкий подход к настройке null = Верно на данный момент. Так тип 2 в командной строке. Затем добавьте это в наш слизняк поле.

# articles/models.py
from django.db import models
from django.urls import reverse


class Article(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    slug = models.SlugField(null=True) # new

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('article_detail', kwargs={'slug': self.slug})

Попробуйте снова создать файл миграции, и он будет работать.

(newspaper) $ python manage.py makemigrations articles

Давай и мигрировать База данных также для применения изменения.

(newspaper) $ python manage.py migrate

Но если вы подумаете об этом, то, что мы сделали, это создать NULL ценность для нашего слизняк Анкет Мы должны перейти в администратор, чтобы правильно его установить. Запустите локальный сервер, Python Manage.py Runserver и перейдите на страницу статьи в администраторе. Слизняк Поле пустое.

Вручную добавить в нашу желаемое значение A-Day-in-the Life и нажмите «Сохранить».

ОК, последний шаг – обновить Статьи/urls.py так что мы отображаем слизняк Аргумент ключевого слова в самом URL. К счастью, это просто означает заменять для Анкет

# articles/urls.py
from django.urls import path

from .views import ArticleListView, ArticleDetailView

urlpatterns = [
    path('', ArticleDetailView.as_view(), name='article_detail'), # new
    path('', ArticleListView.as_view(), name='article_list'),
]

И мы закончили! Перейдите на страницу просмотра списка по адресу http://127.0.0.1:8000/ и нажмите на ссылку для нашей статьи.

И вот с нашим слизняком в качестве URL! Красивый.

Уникальный и нулевой

Двигаясь вперед, мы действительно хотим разрешить NULL ценность для слизняка? Наверное, не так, как сломает наш сайт! Другое соображение: что произойдет, если есть идентичные слизняки? Как это решится? Короткий ответ: не очень хорошо.

Поэтому давайте изменим наше слизняк поле, чтобы NULL не допускается, а уникальные значения требуются.

# articles/models.py
from django.db import models
from django.urls import reverse


class Article(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    slug = models.SlugField(null=False, unique=True) # new

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('article_detail', kwargs={'slug': self.slug})

Сделать миграцию/мигрировать. Нужно пусто для прошлого входа.

(newspaper) $ python manage.py makemigrations articles
You are trying to change the nullable field 'slug' on article to non-nullable without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)
 3) Quit, and let me add a default in models.py
Select an option:

Выберите 2 Поскольку мы можем вручную справиться с существующим рядом, и на самом деле уже есть. Тогда мигрировать база данных.

(newspaper) $ python manage.py migrate

Предварительно заполненные поля

Вручную добавление слизняк Поле каждый раз быстро становится утомительным. Итак, мы можем использовать Предварительный_филд в администраторе для автоматизации процесса для нас.

Обновление Статьи/admin.py следующим образом:

# articles/admin.py
from django.contrib import admin

from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'body',)
    prepopulated_fields = {'slug': ('title',)} # new

admin.site.register(Article, ArticleAdmin)

Теперь зайдите к администратору и добавьте новую статью. Вы заметите, что при вводе в Название поле, Слизняк Поле автоматически заполнено. Довольно аккуратно!

Сигналы, крючки жизненного цикла, сохранение и формы/сериализаторы

В реальном мире он вряд ли просто предоставит администратору доступ к пользователю. Вы могли бы, но в масштабе это определенно не очень хорошая идея. И даже в небольших масштабах большинство нетехнических пользователей найдут веб-интерфейс более привлекательным.

Итак … как автоматически заполнять слизняк Поле при создании новой статьи. Оказывается, у Django есть встроенный инструмент для этого под названием Slugify !

Но как использовать Slugify ? На практике обычно это сделано с помощью Сигнал Анкет Но я бы сказал-как бы Джанго-товарищ Карлтон Гибсон-что это не очень хорошее использование сигналов, потому что мы знаем и отправителя, и получатель здесь. Там нет загадки. Мы подробно обсудим правильное использование сигналов в нашем Эпизод подкаста чата Джанго по теме.

Альтернативой сигналам является использование крючка жизненного цикла через что -то вроде django-lifecycle упаковка. Крюки жизненного цикла – это альтернатива сигналам, которые обеспечивают аналогичную функциональность с меньшим количеством косвенности.

Еще один общий способ увидеть это реализовано – переопределить Статья модель Сохранить метод Анкет Это также «работает», но не лучшее решение. Вот один из способов сделать это.

# articles/models.py
from django.db import models
from django.template.defaultfilters import slugify # new
from django.urls import reverse

class Article(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    slug = models.SlugField(null=False, unique=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('article_detail', kwargs={'slug': self.slug})

    def save(self, *args, **kwargs): # new
        if not self.slug:
            self.slug = slugify(self.title)
        return super().save(*args, **kwargs)

На мой взгляд, лучшее решение – создать слизняк в самой форме. Это можно сделать, переопределив форму Чистый метод так что Cleaned_data Имеет слизняк, или JavaScript может использоваться для автоматической заполнения поля, как это сделано в самой администраторе Джанго. Если вы используете API, тот же подход может быть применен к сериализатору.

Это решение не полагается на пользовательский сигнал и обрабатывает слизняк до это касается базы данных. По словам Карлтона Гибсона, который предложил мне этот подход, беспроигрышный.

Слова осторожности

Быстрое предупреждение об использовании слизняков на большом веб -сайте. Несмотря на то, что требуется, чтобы статья была уникальный Почти неизбежно иметь конфликты именования с использованием слизняков. Однако, похоже, есть хорошие SEO -свойства. Хороший компромисс – объединить слизняк с Uuid или имя пользователя. Поэтому конечный URL будет {{uuid}}/{{slug}} или {{username}}/{{slug}} Анкет Например, если вы посмотрите на GitHub, исходный код для этого учебника – AT https://github.com/wsvincent/django-slug-tutorial которое является именем пользователя + шаблона слизняка. Пока вы мог Также используйте id + Слуг, использование идентификаторов часто является проблемой безопасности, и, по моему мнению, следует избегать производственных сайтов.

Следующие шаги

Если вы хотите сравнить свой код с официальным исходным кодом, его можно найти на GitHub Анкет

Оригинал: “https://dev.to/learndjango/django-slug-tutorial-4all”