Entrega de archivos est谩ticos en Python con Django, AWS S3 y WhiteNoise

     

    Introducci贸n

    Los sitios web generalmente necesitan archivos adicionales como im谩genes, CSS y archivos JavaScript que son necesarios para representar p谩ginas web completas en un navegador. En proyectos peque帽os, podemos trabajar proporcionando rutas absolutas a nuestros recursos o escribiendo funciones CSS y JavaScript en l铆nea en los archivos HTML. Esto no solo va en contra de las mejores pr谩cticas de codificaci贸n, sino que tambi茅n se complica cuando manejamos proyectos m谩s grandes, especialmente con m煤ltiples aplicaciones.

    En Django, los archivos necesarios para la experiencia interactiva del usuario, la presentaci贸n de documentos y las p谩ginas web funcionales se denominan archivos est谩ticos.

    En este art铆culo, veremos c贸mo podemos tratar con m煤ltiples conjuntos de archivos est谩ticos proporcionados por cada aplicaci贸n para personalizar la apariencia de un sitio web.

    Configuraci贸n de archivos est谩ticos

    Django proporciona una enorme flexibilidad sobre c贸mo puede servir los archivos est谩ticos. Cubriremos el uso de archivos est谩ticos en el desarrollo local, as铆 como en la producci贸n, que es un poco m谩s compleja. Primero lo primero, hagamos la configuraci贸n b谩sica.

    Django proporciona django.contrib.staticfiles para ayudarlo a recopilar archivos est谩ticos de cada una de sus aplicaciones (y cualquier otro lugar que especifique) en una sola ubicaci贸n que se puede servir f谩cilmente en producci贸n.

    En tus settings.py archivo, tu INSTALLED_APPS deber铆a verse as铆:

    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 es la ruta que define d贸nde se recopilar谩n sus archivos est谩ticos. Proporcionaremos un camino absoluto para STATIC_ROOT en settings.py.

    Para hacer esto, usaremos el os m贸dulo dirname() funci贸n para obtener el nombre del directorio en el que nos gustar铆a alojar estos archivos y definir la ruta:

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

    Luego, debe especificar un STATIC_URL que es la URL utilizada cuando se hace referencia a archivos est谩ticos. Debe terminar con / si se establece en cualquier valor excepto None. La siguiente ruta significa que los archivos est谩ticos se almacenar谩n en la ubicaci贸n http://localhost:8000/static/ o http://127.0.0.1:8000/static/:

    STATIC_URL = '/static/'
    

    Django tiene una lista de buscadores como STATICFILES_FINDERS que utiliza para localizar archivos est谩ticos. Uno de los buscadores predeterminados es AppDirectoriesFinder que busca una carpeta llamada static dentro de cada uno de tus INSTALLED_APPS.

    Por ejemplo, si su proyecto contiene una aplicaci贸n llamada users, puede crear un directorio como project_name/users/static/index.css para agregar archivos CSS relacionados con esa aplicaci贸n.

    Aunque esto funciona, es una mejor idea crear otro subdirectorio con el nombre de su aplicaci贸n, como project_name/users/static/users/index.css. Esto es importante cuando tenemos dos o m谩s archivos est谩ticos con nombres similares.

    Consideremos que tienes un index.css en cada aplicaci贸n, cada una de las cuales contiene diferentes estilos CSS. Django buscar谩 el primero index.css podr铆a encontrar en app/static/ directorios. No podr谩 distinguir entre varios index.css que tenemos en cada aplicaci贸n static directorio. Por eso creamos un subdirectorio con el nombre de la aplicaci贸n app/static/app/.

    Adem谩s, la mayor铆a de los proyectos tienen varias aplicaciones que pueden tener archivos est谩ticos comunes, por lo que generalmente es mejor crear una carpeta static en el directorio ra铆z de su proyecto en lugar de hacer un static carpeta en cada aplicaci贸n:

    Para utilizar un lugar com煤n para todos los archivos est谩ticos en el directorio de su proyecto, necesitamos configurar STATICFILES_DIRS para informar a Django sobre nuestro nuevo directorio porque AppDirectoriesFinder buscar谩 static en app directorios solamente. Tambi茅n podemos definir m煤ltiples ubicaciones para nuestros archivos est谩ticos.

    Este es el lugar para definir las carpetas est谩ticas de proyectos individuales si tiene varias:

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

    Tenga en cuenta que STATICFILES_DIRS solo funcionar谩 si no quita FileSystemFinder desde STATICFILES_FINDERS.

    Como breve recapitulaci贸n, nuestro settings.py incluir:

    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'),
    )
    

    Los archivos est谩ticos est谩n listos para usarse en su proyecto. Solo necesitamos cargar el static etiqueta de plantilla por {% load static %} y luego usa el static etiqueta de plantilla para crear la URL de la ruta relativa dada. Veamos c贸mo podemos usar archivos est谩ticos en nuestro archivo de plantilla. 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>
    

    los base.html incluye una head.html plantilla para una segregaci贸n adecuada, ya que los proyectos m谩s grandes suelen contener un c贸digo extenso en head etiquetas los mainbtn clase para h1 se define en el static/index.css archivo. La imagen de fondo bg.png tambi茅n est谩 presente en static directorio.

    los head.html Se ve como esto:

    <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>
    

    Entrega de archivos est谩ticos

    Adem谩s de las configuraciones anteriores, tambi茅n necesitamos servir los archivos est谩ticos. Lo hace autom谩ticamente Django runserver comando si Debug = True. Debe utilizar este m茅todo en la fase de desarrollo ya que es f谩cil, sin embargo, no se recomienda para producci贸n porque es ineficiente e inseguro.

    Django viene con un comando incorporado collecstatic. Compila todos los archivos est谩ticos en un solo directorio STATIC_ROOT que ya configuramos. La pieza final es el motor de almacenamiento que se utiliza al recopilar archivos est谩ticos con el collectstatic mando. El motor de almacenamiento se puede configurar mediante STATICFILES_STORAGE. Django tiene su propio motor de almacenamiento, por lo que el valor predeterminado de STATICFILES_STORAGE se establece en django.contrib.staticfiles.storage.StaticFilesStorage.

    Archivos est谩ticos en producci贸n

    Hay dos pasos principales para colocar archivos est谩ticos en un entorno de producci贸n:

    • Ejecutar el collectstatic comando cada vez que cambian los archivos est谩ticos
    • Arreglos para STATIC_ROOT para ser movido al servidor de archivos est谩ticos y servido

    los post_process() m茅todo del Storage la clase puede encargarse del segundo paso, pero realmente depende de su motor de almacenamiento, es decir STATICFILES_STORAGE.

    Nota: Debe saber que el servicio de archivos est谩ticos en cada producci贸n ser谩 diferente debido a la diferencia en los entornos, pero la idea b谩sica y los pasos siguen siendo los mismos. Hay tres t谩cticas principales para manejar los archivos est谩ticos en producci贸n:

    • Sirva los archivos est谩ticos y el sitio desde el mismo servidor: Utilice este m茅todo si desea que sus archivos est谩ticos sean servidos desde el servidor que ya est谩 ejecutando su aplicaci贸n web. A pesar de su posible problema de rendimiento, podr铆a ser rentable ya que solo necesita pagar por el alojamiento de un servidor. Para hacer esto, env铆e su c贸digo al servidor de implementaci贸n y luego ejecute collectstatic para copiar todos los archivos a STATIC_ROOT. Por 煤ltimo, configure su servidor web para servir los archivos est谩ticos en STATIC_URL.
    • Sirviendo archivos est谩ticos desde un servidor dedicado: Las opciones m谩s comunes para servidores de archivos est谩ticos dedicados son nginx y versi贸n reducida de Apache. La aplicaci贸n web se ejecuta en un servidor completamente diferente, mientras que sus archivos est谩ticos se implementan en un servidor dedicado que brinda un rendimiento m谩s r谩pido en general. correr collectstatic localmente siempre que los archivos est谩ticos cambien y luego empuje STATIC_ROOT al directorio de su servidor dedicado que se est谩 sirviendo. Para obtener instrucciones detalladas, debe consultar la documentaci贸n del servidor correspondiente.
    • Entrega de archivos est谩ticos desde un servicio en la nube: Otra t谩ctica com煤n es entregar archivos est谩ticos de un proveedor de almacenamiento en la nube como Amazon, Microsoft Azure y Alibaba Cloud.

    Veamos c贸mo podemos usar Amazon S3 para este prop贸sito. Primero, instale dos bibliotecas de Python usando estos comandos:

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

    los boto3 library es un cliente API p煤blico para acceder a Amazon S3 y otros servicios web de Amazon (AWS). los django-storages gestiona backends de almacenamiento como Amazon S3, OneDrive, etc. Se conecta a la API de backend de almacenamiento Django incorporada. Tambi茅n necesitar谩 agregar storages en tus INSTALLED_APPS. Nuestra INSTALLED_APPS como se ve as铆 por ahora:

    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
    ]
    

    Despu茅s de eso, agregue las siguientes configuraciones en su 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'
    

    Finalmente, corre python manage.py collectstatic y habr谩 terminado de configurar Amazon S3 para sus archivos est谩ticos.

    Entrega de archivos est谩ticos con WhiteNoise

    Las personas a menudo no usan servicios en la nube de terceros como Amazon S3 por un par de razones, incluidas las suscripciones pagas. WhiteNoise permite que su proyecto Django sirva sus propios archivos est谩ticos, lo que lo convierte en una unidad aut贸noma que podemos implementar en cualquier lugar sin depender de los proveedores de servicios.

    Aunque funciona con cualquier aplicaci贸n web compatible con WSGI, se configura m谩s f谩cilmente con un proyecto de Django.

    Configuraci贸n para WhiteNoise

    Vamos a instalar Ruido blanco con:

    $ pip install whitenoise
    

    En tus settings.py, agregue WhiteNoise al MIDDLEWARE lista en el siguiente orden:

    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',
      ]
    

    Para utilizar el soporte de compresi贸n y los archivos que se pueden almacenar en cach茅 para siempre, agregue esto en su settings.py
    STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

    correr python manage.py collectstatic.

    隆Eso es! Ahora puede implementar su aplicaci贸n web en cualquier plataforma de alojamiento, como Heroku.

    Conclusi贸n

    Todo desarrollador de sitios web necesita archivos est谩ticos para crear un sitio web atractivo y funcional. Django no solo ofrece una configuraci贸n sencilla de archivos est谩ticos, sino tambi茅n una enorme flexibilidad para jugar con su implementaci贸n.

    En este art铆culo, cubrimos varias formas de integrar archivos est谩ticos en una aplicaci贸n web Django tanto en el desarrollo local como en la producci贸n.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *