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

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

В этой статье мы рассмотрим, как обслуживать статические файлы с помощью Django, включая примеры обслуживания статических файлов локально и в производстве с использованием AWS S3 и WhiteNoise.

Автор оригинала: Muhammad Hashir Hassan.

Вступление

Веб-сайты обычно нуждаются в дополнительных файлах, таких как изображения, 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 in settings.py .

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

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 в каждом приложении:

статическая папка каталог

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

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

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

Обратите внимание, что STATIC FILES_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 template с помощью {% load static%} , а затем использовать тег static template для построения URL-адреса для данного относительного пути. Давайте посмотрим, как мы можем использовать статические файлы в вашем файле шаблона base.html :



{% load static %}

    {% include 'head.html' %}
 
  
      

MY CUSTOM CSS CLASS

{% block content %}
{% endblock %}

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

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


    {% block css_block %}{% endblock %}
    {% load static %}
    
    
    
    
    
    
    
    {% block title %} Title to be changed in included files {% endblock %}

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

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

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

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

Существует два основных шага для размещения статических файлов в рабочей среде:

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

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

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

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

  • Обслуживание статических файлов с выделенного сервера: Наиболее распространенными вариантами для выделенных статических файловых серверов являются nginx и урезанная версия Apache . Веб-приложение работает на совершенно другом сервере, в то время как ваши статические файлы развертываются на выделенном сервере, что в целом обеспечивает более высокую производительность. Запускайте 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 и т. Д. Он подключается к встроенному интерфейсу Django storage backend API. Вам также нужно будет добавить storages в ваш INSTALLED_APPS . Наш INSTALLED_APPS like уже выглядит так:

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 для ваших статических файлов.

Обслуживание Статических Файлов С Использованием Белого Шума

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

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

Конфигурация для белого шума

Давайте установим Белый шум с:

$ pip install whitenoise

В вашем settings.py , добавьте Белый шум в список 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 STATIC FILES_STORAGE

Run python manage.py collectstatic .

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

Вывод

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

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