В первую очередь необходимо предоставить пользователю несколько возможностей для поглощения контента.
Например, не всегда удобно заходить на сайт проекта ежедневно, особенно если новый материал появляется нерегулярно или, например, у вас большой список ресурсов, которые необходимо посещать.
В таком случае удобнее всего подписаться на сайт и получать уведомления о появлении новых публикаций.
Для лучшей индексации материала поисковыми службами следует составить карту сайта и держать ее актуальной.
Ссылки на содержимое конкретных статей необходимо составить с использованием заголовка публикации, для удобства восприятия и возможно для продвижения в поисковых системах.
Вдобавок необходимо разработать механизм, который предотвратит недоступность материала в случае если заголовок статьи по каким-либо причинам был изменен.
Представления
В директории приложения открываем views.py и наполняем следующим:
from django.shortcuts import render, get_object_or_404, redirect
from .models import Article
def index_view(request):
articles = Article.public.all()
return render(request, 'articles/index.html', {
'articles': articles,
})
def article_view(request, slug, pk):
if request.user.is_superuser:
# получаем все объекты для предварительного просмотра
queryset = Article.objects
else:
queryset = Article.public
article = get_object_or_404(queryset, pk=pk)
if article.slug != slug:
# делаем постоянный редирект, слаг был изменен
return redirect(article, permanent=True)
return render(request, 'articles/article.html', {
'article': article,
})
Первое представление покажет нам список всех опубликованных статей на данный момент.
Второе представление призвано показать нам содержимое конкретной статьи.
В самом начале представления мы проверяем права посетителя, если в систему зашел супер-пользователь, то получаем все объекты, для того чтоб была возможность оценить, как будет выглядеть статья до ее публикации.
Далее мы пытаемся найти статью по ее идентификатору, затем проверяем чтоб слаг из ссылки был равен текущему слагу статьи и если необходимо поправляем маршрут.
Например, при первой публикации статьи, мы получили следующую ссылку:
/articles/staryi-zagolovok-stati-14/
Здесь мы видим слаг и идентификатор статьи, человекоподобные маршруты читаются намного легче и для пользователя, и для поисковых систем, именно поэтому слаг располагается первым.
Иногда в процессе работы появляется необходимость изменить заголовок статьи, например, добавить слово и соответственно после сохранения маршрут изменится:
/articles/novyi-zagolovok-stati-14/
Но у пользователя или поисковых систем мог остаться старый маршрут, и чтоб не показывать ошибку 404, мы ищем статью только по ее идентификатору, и в случае если слаги различаются — перенаправляем на новый маршрут с пометкой, что данная статья перемещена, ведь для нас каждый заход на сайт важен.
Лента последних публикаций
В Django присутствуют инструменты для создания лент, нам необходимо только описать класс указывая свои настройки и затем подключить представление к маршрутам.
В каталоге приложения создаем файл feeds.py:
from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Atom1Feed
from django.urls import reverse_lazy
from django.conf import settings
from .models import Article
class LatestArticlesFeed(Feed):
feed_type = Atom1Feed
title = settings.SITE_TITLE
link = reverse_lazy('articles:index')
subtitle = settings.SITE_SUBTITLE
author_name = settings.SITE_AUTHOR
def items(self):
return Article.public.all()[:settings.ARTICLES_ITEMS_IN_FEED]
def item_title(self, item):
return item.title
def item_description(self, item):
return item.summary
def item_pubdate(self, item):
return item.published
def item_updateddate(self, item):
return item.updated
Ленты можно выводить в двух форматах: RSS и Atom. Последний более продвинутый — мы используем его.
Далее устанавливаем заголовок и подзаголовок ленты с указанием авторства и ссылки на страницу статей.
Для создания ссылки используется "ленивая" функция, все дело в том, что при подключении представления ленты, список маршрутов может быть еще не подключен.
Затем мы начинаем работать непосредственно с объектами ленты.
В методе items мы получаем только публичные объекты с заданным ограничением, которое установим чуть позже. Количество зависит от частоты появления нового материала. Например, если вы публикуете статью раз в неделю, то последние десять публикаций будут вполне уместным выбором.
Остальные методы позволяют нам внести подробности к каждому объекту, указывая заголовок, резюме, дату публикации и обновления статьи.
Карта статей
Функционал для создания карты сайта тоже присутствует в арсенале Django.
В директории приложения создаем файл sitemaps.py:
from django.contrib.sitemaps import GenericSitemap
from .models import Article
articles_sitemaps = {
'articles': GenericSitemap({
'queryset': Article.public,
'date_field': 'updated',
}, priority=1.0, changefreq=None),
}
Здесь мы указываем только публичные статьи с датой последнего обновления.
Выставляем максимальный приоритет поскольку статьи — это самый важный контент на сайте.
Настройки
Открываем файл настроек проекта settings.py и добавляем:
ARTICLES_ITEMS_IN_FEED = 20 # кол-во статей в фиде
Далее добавляем приложение sitemaps:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
'ckeditor',
'ckeditor_uploader',
'core.apps.CoreConfig',
'accounts.apps.AccountsConfig',
'articles.apps.ArticlesConfig',
]
Маршруты
В каталоге приложения создаем файл urls.py:
from django.conf.urls import url
from . import views
from .feeds import LatestArticlesFeed
app_name = 'articles'
urlpatterns = [
url(r'^$', views.index_view, name='index'),
url(r'^feed/$', LatestArticlesFeed(), name='feed'),
url(r'^(?P<slug>[\w-]+)-(?P<pk>\d+)/$', views.article_view, name='article'),
]
В директории проекта переходим в каталог zero, затем открываем urls.py и приводим к следующему виду:
from django.conf.urls import url, include
from django.contrib import admin
from django.views.generic.base import RedirectView
from django.contrib.sitemaps.views import sitemap
from django.conf.urls.static import static
from django.conf import settings
from articles.sitemaps import articles_sitemaps
sitemaps = {}
sitemaps.update(articles_sitemaps)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^ckeditor/', include('ckeditor_uploader.urls')),
url(r'^accounts/', include('accounts.urls')),
url(r'^articles/', include('articles.urls')),
url(r'^$', RedirectView.as_view(pattern_name='articles:index'), name='index'),
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}, name='sitemap'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# Django Debug Toolbar
if settings.DEBUG:
import debug_toolbar
urlpatterns += [
url(r'^__debug__/', include(debug_toolbar.urls)),
]
Мы подключили маршруты приложения articles и установили на него перенаправление с главной страницы сайта.
Затем подключили представление карты сайта для поисковых систем.