Обслуживание статических файлов в Python с помощью Django, AWS S3 и WhiteNoise

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

Вступление

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

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

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

Настройка статических файлов

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

Django предоставляет django.contrib.staticfiles чтобы помочь вам собрать статические файлы из каждого из ваших приложений (и любых других мест, которые вы укажете) в единое место, которое можно легко использовать в производственной среде.

В вашем файле settings.py INSTALLED_APPS должен выглядеть так:

 INSTALLED_APPS = [ 
 'django.contrib.auth', 
 'django.contrib.sites', 
 'django.contrib.contenttypes', 
 'django.contrib.admin', 
 'django.contrib.sessions', 
 'django.contrib.messages', 
 'django.contrib.staticfiles', # To serve static files 
 ] 

STATIC_ROOT - это путь, который определяет, где будут собираться ваши статические файлы. Мы предоставим абсолютный путь к STATIC_ROOT в settings.py .

Для этого мы воспользуемся dirname() модуля os , чтобы получить имя каталога, в котором мы хотели бы разместить эти файлы, и определить путь:

 import os 
 
 PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 
 STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') 

Затем вам необходимо указать STATIC_URL который является URL-адресом, используемым при обращении к статическим файлам. Оно должно заканчиваться символом / если установлено любое значение, кроме None . Следующий путь означает, что статические файлы будут храниться в расположении http://localhost:8000/static/ или http://127.0.0.1:8000/static/ :

 STATIC_URL = '/static/' 

Django имеет список средств STATICFILES_FINDERS который он использует для поиска статических файлов. Одним из средств AppDirectoriesFinder который ищет папку с именем static в каждом из ваших INSTALLED_APPS .

Например, если ваш проект содержит приложение с именем users , вы можете создать каталог, например project_name/users/static/index.css чтобы добавить файлы CSS, связанные с этим приложением.

Несмотря на то, что это работает, лучше создать другой подкаталог с именем вашего приложения, например project_name/users/static/users/index.css . Это важно, когда у нас есть два или более статических файла с похожими именами.

Предположим, у вас есть index.css в каждом приложении, каждое из которых содержит разные стили CSS. Django будет искать первый index.css app/static/ . Он не сможет различать различные index.css , которые есть в static каталоге каждого приложения. Вот почему мы создали подкаталог с именем app/static/app/ .

Кроме того, в большинстве проектов есть несколько приложений, которые могут иметь общие статические файлы, поэтому обычно лучше сделать папку static в корневом каталоге вашего проекта, а не создавать static папку в каждом приложении:

каталог статическойпапки{.ezlazyload}

Чтобы использовать банальность для всех статических файлов в директории проекта, нам нужно настроить STATICFILES_DIRS сообщить Django о нашем новом каталоге , потому что AppDirectoriesFinder будет искать static в app только каталогах. Мы также можем определить несколько местоположений для наших статических файлов.

Это место для определения статических папок отдельного проекта, если у вас их несколько:

 STATICFILES_DIRS = ( 
 os.path.join(PROJECT_ROOT, 'static'), 
 # Extra lookup directories for collectstatic to find static files 
 ) 

Обратите внимание, что STATICFILES_DIRS будет работать, только если вы не удалите FileSystemFinder из STATICFILES_FINDERS .

Вкратце, наш файл settings.py включает:

 import os 
 
 PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) 
 STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') 
 STATIC_URL = '/static/' 
 
 # Extra lookup directories for collectstatic to find static files 
 STATICFILES_DIRS = ( 
 os.path.join(PROJECT_ROOT, 'static'), 
 ) 

Статические файлы готовы к использованию в вашем проекте. Нам просто нужно загрузить static шаблона с помощью {% load static %} а затем использовать static шаблона для создания URL-адреса для заданного относительного пути. Давайте посмотрим, как мы можем использовать статические файлы в нашем файле шаблона base.html :

 <!doctype html> 
 {% load static %} 
 <html lang="en"> 
 {% include 'head.html' %} 
 <style> 
 body{ 
 background: url('{% static "bg.png" %}') no-repeat center center fixed; 
 -webkit-background-size: cover; 
 -moz-background-size: cover; 
 -o-background-size: cover; 
 background-size: cover; 
 } 
 </style> 
 <body> 
 <div class="row justify-content-center"> 
 <div class="col-8"> 
 <h1 class="mainbtn">MY CUSTOM CSS CLASS</h1> 
 {% block content %} 
 <hr class="mt-0 mb-4"> 
 {% endblock %} 
 </div> 
 </div> 
 </div> 
 </body> 
 </html> 

base.html включает в себя head.html шаблон для надлежащего разделения , как крупные проекты , как правило , содержат длинный код в head теги. Класс mainbtn для h1 определен в файле static/index.css Фоновое изображение bg.png также присутствует в static директории.

head.html выглядит так:

 <head> 
 {% block css_block %}{% endblock %} 
 {% load static %} 
 <meta charset="utf-8"> 
 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 
 
 <link rel="stylesheet" href="{% static 'css/index.css' %}"> 
 <script src="{% static 'js/functions.js' %}"></script> 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> 
 
 <title>{% block title %} Title to be changed in included files {% endblock %}</title> 
 </head> 

Обслуживание статических файлов

В дополнение к вышеуказанным конфигурациям нам также необходимо обслуживать статические файлы. Это автоматически выполняется командой Django runserver если Debug = True . Вы должны использовать этот метод на этапе разработки, поскольку он прост, однако он не рекомендуется для производства, поскольку он неэффективен и небезопасен.

Django имеет встроенную команду collecstatic . Он компилирует все статические файлы в один каталог STATIC_ROOT который мы уже установили. Последняя часть - это механизм хранения, используемый при сборе статических файлов с помощью команды collectstatic Механизм хранения можно настроить с помощью STATICFILES_STORAGE . Django имеет собственный механизм хранения, поэтому значение по умолчанию для STATICFILES_STORAGE установлено на django.contrib.staticfiles.storage.StaticFilesStorage .

Статические файлы в производстве

Чтобы поместить статические файлы в производственную среду, нужно выполнить два основных шага:

  • Запускайте команду collectstatic всякий раз, когда изменяются статические файлы
  • Организуйте STATIC_ROOT на статический файловый сервер и обслуживание

Метод post_process() Storage может позаботиться о втором шаге, но это действительно зависит от вашего механизма хранения, то есть STATICFILES_STORAGE .

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

  • Обслуживайте статические файлы и сайт с одного сервера: используйте этот метод, если вы хотите, чтобы ваши статические файлы обслуживались с сервера, на котором уже запущено ваше веб-приложение. Несмотря на потенциальную проблему с производительностью, это может быть рентабельным, поскольку вам нужно заплатить только за один хостинг сервера. Для этого отправьте свой код на сервер развертывания, затем запустите collectstatic чтобы скопировать все файлы в STATIC_ROOT . Наконец, настройте свой веб-сервер для обслуживания статических файлов под STATIC_URL .

  • Обслуживание статических файлов с выделенного сервера: наиболее распространенный выбор для выделенных серверов статических файлов - это nginx и урезанная версия Apache . Веб-приложение работает на совершенно другом сервере, в то время как ваши статические файлы развертываются на выделенном сервере, что в целом обеспечивает более высокую производительность. STATIC_ROOT collectstatic локально при изменении статических файлов, затем нажмите STATIC_ROOT в каталог вашего выделенного сервера, который обслуживается. Для получения подробных инструкций вы должны проверить документацию соответствующего сервера.

  • Обслуживание статических файлов из облачной службы. Другой распространенной тактикой является обслуживание статических файлов от поставщика облачного хранилища, такого как Amazon, Microsoft Azure и Alibaba Cloud.

Давайте посмотрим, как мы можем использовать Amazon S3 для этой цели. Сначала установите две библиотеки Python с помощью этих команд:

 $ python -m pip install boto3 
 $ pip install django-storages 

Библиотека boto3 - это общедоступный клиент API для доступа к Amazon S3 и другим веб-сервисам Amazon (AWS). django-storages управляет серверными модулями хранилища, такими как Amazon S3, OneDrive и т. Д. Он подключает встроенный API хранилища Django. Вам также нужно будет добавить storages в INSTALLED_APPS . Наш INSTALLED_APPS выглядит так:

 INSTALLED_APPS = [ 
 'django.contrib.auth', 
 'django.contrib.sites', 
 'django.contrib.contenttypes', 
 'django.contrib.admin', 
 'django.contrib.sessions', 
 'django.contrib.messages', 
 'django.contrib.staticfiles', 
 'users', 
 'storages', # New 
 ] 

После этого добавьте следующие конфигурации в свой settings.py :

 AWS_ACCESS_KEY_ID = your_access_key_id 
 AWS_SECRET_ACCESS_KEY = your_secret_access_key 
 AWS_STORAGE_BUCKET_NAME = 'sibtc-static' 
 AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME 
 AWS_S3_OBJECT_PARAMETERS = { 
 'CacheControl': 'max-age=86400', 
 } 
 AWS_LOCATION = 'static' 
 
 STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION) 
 STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' 

Наконец, запустите python manage.py collectstatic и вы закончите настройку Amazon S3 для ваших статических файлов.

Обслуживание статических файлов с помощью WhiteNoise

Люди часто не используют сторонние облачные сервисы, такие как Amazon S3, по нескольким причинам, включая платные подписки. WhiteNoise позволяет вашему проекту Django обслуживать свои собственные статические файлы, что делает его автономным модулем, который мы можем развернуть где угодно, независимо от поставщиков услуг.

Хотя он работает с любым WSGI-совместимым веб-приложением, его проще всего настроить с помощью проекта Django.

Конфигурация для WhiteNoise

Давайте установим WhiteNoise с помощью:

 $ pip install whitenoise 

В settings.py добавьте WhiteNoise в MIDDLEWARE в следующем порядке:

 MIDDLEWARE = [ 
 'django.middleware.security.SecurityMiddleware', 
 # WhiteNoise Middleware above all but below Security 
 'whitenoise.middleware.WhiteNoiseMiddleware', 
 'django.contrib.sessions.middleware.SessionMiddleware', 
 'django.middleware.common.CommonMiddleware', 
 'django.middleware.csrf.CsrfViewMiddleware', 
 'django.contrib.auth.middleware.AuthenticationMiddleware', 
 'django.contrib.messages.middleware.MessageMiddleware', 
 ] 

Чтобы использовать поддержку сжатия и файлы, кэшируемые навсегда, добавьте это в свой settings.py
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Запустите python manage.py collectstatic .

Это оно! Теперь вы можете развернуть свое веб-приложение на любой платформе хостинга, такой как Heroku .

Заключение

Каждому разработчику веб-сайтов нужны статические файлы, чтобы сделать красивый и функциональный веб-сайт. Django предлагает не только простую настройку статических файлов, но и огромную гибкость при их развертывании.

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

comments powered by Disqus