Файловый хостинг Amazon S3 + Django + Heroku

Django — библиотека для создания сайтов на языке Python.

Heroku — платформа, которая позволяет размещать сайты, сделанные на Django.

Heroku не предоставляет постоянного хранилища для файлов, которые пользователь загружает через сайт, поэтому необходимо воспользоваться каким-то сторонним сервисом, например, Amazon S3.

Допустим, что мы уже зарегистрировались на Heroku и Amazon.

Настройка Amazon

Перейдем в My Security Credentials (учетные данные безопасности).

My Security Credentials

Создадим новый ключ доступа с помощью кнопки Create New Access Key.

Create New Access Key

Появится окно с идентификатором ключа и секретным ключом. Их надо сохранить, чтобы потом настроить Heroku. Сохранить можно в файл с помощью кнопки Download Key File.

Access Key

Теперь нужно перейти в Amazon S3 и создать хранилище (кнопка Create Bucket).

Amazon S3

Зададим DNS-совместимое имя хранилища и регион такой же как на Heroku, чтобы минимизировать задержки при передаче данных. Остальные настройки можно оставить без изменения. Имя понадобится для настройки Heroku.

Create Bucket

Работать с файлами и папками хранилища можно прямо в браузере. Можно создавать папки, загружать файлы, удалять то и другое, переименовывать, перемещать, копировать и прочее.

При загрузке файла создается ссылка на него, по которой он будет доступен в интернете.

Загрузим один файл, чтобы узнать по какому адресу располагается наше хранилище. Адрес зависит от выбранного региона. Часть ссылки, которая подчеркнута красным, понадобится для настройки Heroku.

example.txt

Настройка Heroku

Перейдем в настройки приложения и назначим переменные окружения, которые здесь называются Config Variables.

Heroku Config Variables

Требуется назначить 4 переменные окружения на основе настроек Amazon:

  • AWS_ACCESS_KEY_ID — идентификатор ключа.
  • AWS_SECRET_ACCESS_KEY — секретный ключ.
  • AWS_STORAGE_BUCKET_NAME — имя хранилища.
  • AWS_URL — адрес, по которому располагается хранилище.

Настройка проекта Django

Для работы с Amazon S3 нужно установить пакеты django-storages и boto3.

  • django-storages — это коллекция хранилищ для Django.
  • boto3 — библиотека для работы с сервисами Amazon.

Если используется файл requirements.txt для удовлетворения зависимостей, то в него нужно прописать пакеты нужных версий, например:

django-storages==1.6.5
boto3==1.4.7

Установить пакеты можно следующей командой:

pip install -r requirements.txt

В файле settings.py нужно прописать следующий код.

INSTALLED_APPS = (
    ...
    'storages',
    ...
)

AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_URL = os.environ.get('AWS_URL')

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

AWS_MEDIA_URL = "{}/{}/".format(AWS_URL, AWS_STORAGE_BUCKET_NAME)

MEDIA_URL = AWS_MEDIA_URL

Продолжение будет…

Добавление Sitemap с помощью DjangoCMS

Sitemap — XML-файлы с информацией для поисковых систем (таких как Google, Яндекс, Bing, Поиск@Mail.Ru) о страницах веб-сайта, которые подлежат индексации.

DjangoCMS может самостоятельно сгенерировать Sitemap с опубликованными на сайте страницами.

Настроить выдачу Sitemap очень просто, следуя следующей инструкции.

  1. В файле настроек settings.py добавляем django.contrib.sitemaps в INSTALLED_APPS.
  2. Добавляем следующую строчку в начало файла urls.py.
    from cms.sitemaps import CMSSitemap
  3. В том же файле (urls.py) добавляем в список urlpatterns следующий код.
    url(
        r'^sitemap\.xml$',
        'django.contrib.sitemaps.views.sitemap',
        {'sitemaps': {'cmspages': CMSSitemap}}
    ),
    
  4. Запускаем локальный сайт. Вводим в адресную строку браузера http://127.0.0.1:8000/sitemap.xml (или кликаем по ссылке) и убеждаемся в наличие Sitemap.

Ссылки

How to create sitemaps (официальная документация на английском)

Openshift и Django: раздача загруженных файлов

Интерфейс сайта может позволять пользователю загружать файлы. Файлы должны загружаться в папку, которая указана в переменной MEDIA_ROOT в файле settings.py следующим образом.

MEDIA_ROOT = os.path.join(os.environ['OPENSHIFT_DATA_DIR'], 'media')

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

При использовании Django-CMS, файлы загружаются именно в MEDIA_ROOT.

Но есть сложность с раздачей этих файлов. Django не имеет инструментов для раздачи загруженных файлов на боевом сервере.

Чтобы раздавать загруженные файлы надо пойти на хитрость. Сделать так, чтобы они раздавались как static-файлы.

static-файлы автоматически собираются в папку, которая указана в переменной STATIC_ROOT.

Читать далее Openshift и Django: раздача загруженных файлов

Отладка Django-сайта на боевом сервере OpenShift

Ни в коем случае нельзя включать отладку на боевом сервере. Рекомендуется создать копию сервера, недоступную для пользователя.

В файле settings.py задается переменная DEBUG. Если при загрузке страницы произошла ошибка, то в зависимости от значения этой переменной выдается либо страница с HTTP ошибкой, либо страница с отладочной информацией.

На локальном сервере разработчика значение DEBUG равно True большую часть времени, а на боевом сервере значение DEBUG должно быть всегда равно False. Но можно создать тестовый сервер, копию боевого, где значением DEBUG можно управлять.

Следующий код позволяет включать и отключать отладку на локальном сервере и на сервере Openshift. Код располагается в файле settings.py.

import os
ON_PAAS = 'OPENSHIFT_REPO_DIR' in os.environ
LOCAL_DEBUG = True
ENV_DEBUG = os.environ.get('DEBUG') == 'True'

DEBUG = (not ON_PAAS and LOCAL_DEBUG) or (ON_PAAS and ENV_DEBUG)

if ON_PAAS and DEBUG:
    print("Warning: debug mode!")

Переменная ON_PAAS равна True если код выполняется на сервере Openshift, иначе она равна False. Переменная LOCAL_DEBUG включает или отключает локальную отладку.

При отключении отладки на локальном сервере в список ALLOWED_HOSTS должна быть добавлена строка ‘localhost’.

ALLOWED_HOSTS = ['localhost']

Включить отладку на сервере Openshift можно если создать переменную окружения DEBUG со значением True.

Управлять переменными окружения на Openshift можно с помощью инструмента rhc. Следующие команды включают отладку на сервере Openshift.

rhc env set DEBUG=True -a test
rhc app stop -a test
rhc app start -a test

Где test — это имя приложения. Первая команда устанавливает переменную окружения, а две другие перезапускают приложение.

Отключить отладку можно следующими командами.

rhc env unset DEBUG -a test
rhc app stop -a test
rhc app start -a test

Вместо первой команды можно использовать следующую команду.

rhc env set DEBUG=False -a test

 

Django: шаблон в зависимости от режима отладки

Хочу привести рецепт того, как с помощью создания собственного шаблонного тега заставить меняться шаблон в зависимости от режима отладки.

Режимом отладки управляет переменная DEBUG в файле settings.py. Если DEBUG == True, то Django выводит отладочную информацию при возникновении ошибок.

Отладка должна быть выключена на боевом сервере и включена на сервере разработки. Это правило можно использовать, чтобы на основании переменной DEBUG, определять на каком сервере мы находимся.

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

При написании статьи я использовал Django версии 1.8.

Собственный тег можно определить только в приложении, поэтому создадим приложение app_for_template_tags командой:


python3 manage.py startapp app_for_template_tags

Приложение необходимо добавить в INSTALLED_APPS в файле settings.py:

INSTALLED_APPS = (
    # Другие приложения,
    'app_for_template_tags',
)

Теги должны определяться в пакете templatetags, поэтому надо создать папку templatetags с пустым файлом __init__.py в каталоге app_for_template_tags.

Создадим модуль в котором будет определение тега. Пусть модуль называется debug_mode_tag.py.

Содержимое debug_mode_tag.py:

from django import template
from django.conf import settings

register = template.Library()

@register.assignment_tag
def debug_mode_tag():
     return settings.DEBUG

Имя функции debug_mode_tag соответствует имени нового тега. Имя файла не обязательно должно совпадать с именем функции. Кроме того функций может быть несколько.

Если разработка ведется на сервере разработчика и включен режим отладки, то функция debug_mode_tag вернет True, иначе False.

В шаблоне тег используется следующим образом:

{% load debug_mode_tag %}

{% debug_mode_tag as debug_mode %}

{% if debug_mode %}
  <!-- Html-код, который будет
  показан, если включена отладка. -->
{% endif %}

В первой строке подключается модуль debug_mode_tag. Во второй строке создается переменная debug_mode, значение которой будет равно значению, которое вернула функция debug_mode_tag.

Итог

Для решения понадобилось создать файловую структуру:

Django тег debug_mode_tag

Создать функцию в модуле debug_mode_tag.py и добавить приложение в settings.py.

Подробное описание создания тегов можно почитать в документации на Django.

Установка Python и Django и запуск веб-приложения на Windows

  1. Скачайте Python последней версии с официального сайта.
  2. При установке выберите «Add python.exe to Path», чтобы была возможность запускать Python в командной строке.
    Установка переменной PATH
  3. После установки запустите командную строку и установите Django командой:
    pip install django

    pip — это менеджер пакетов, который позволяет устанавливать программы, написанные на Python из специального репозитория.

  4. После установки Django перейдите в папку с веб-приложением:
    cd "путь к папке содержащей файл manage.py"
  5. Запустите веб-приложение:
    python manage.py runserver

    Запустится простой веб-сервер, встроенный в Django.

  6. В браузере откройте адрес http://localhost:8000/.