2010-01-14 14 views
13

Antecedentes:¿Cómo deberían las aplicaciones Django agrupar medios estáticos?

estoy empezando a utilizar Django, por primera vez, que también es mi primera incursión en el desarrollo web. Me quedé atrapado en el problema de "servir multimedia estática". Después de pasar un rato mirando toda la documentación y las preguntas de StackOverflow, creo que entiendo cómo se supone que debe funcionar (es decir, MEDIA_ROOT, MEDIA_URL, actualización del archivo de URL, etc.).

Mi pregunta:

Ok, así que aquí está la parte que no estoy seguro. Se supone que las aplicaciones de Django son "conectables", es decir, puedo mover una aplicación de un proyecto a otro. Entonces, ¿cómo deben estas aplicaciones agrupar medios estáticos?

Por ejemplo, supongamos que tengo una aplicación "foo", que tiene plantillas que cargan algunos archivos css/image. ¿Dónde se supone que debo poner estos archivos para que se publiquen automáticamente una vez que incluya la aplicación?

La única solución que veo es que la instalación de una aplicación debe incluir el paso adicional de copiar sus medios estáticos en algún lugar de su propio servidor que sirva a ese medio.

¿Es esta la forma aceptada de hacerlo? Incluye un paso adicional, pero tal vez eso sea estándar cuando se trata de web-dev (soy nuevo, así que realmente no lo sé).

Además, si este es el camino, ¿existe una forma estándar de recopilar todos mis medios estáticos para que sea más fácil saber lo que necesito para servir? (Es decir, ¿es estándar tener una carpeta llamada "media" o algo dentro de la aplicación?).

Gracias,

Respuesta

9

Convención es poner los medios estáticos, ya sea en los medios de comunicación/nombreaplic/o estático/nombreaplic/dentro de la aplicación (similar a las plantillas).

Para usar aplicaciones en su proyecto que vienen con medios, recomiendo usar django-staticfiles. Servirá automáticamente los medios (incluidos los medios dentro de las aplicaciones) en desarrollo a través de una vista que reemplaza a django.views.static.serve, y viene con un comando de administración build_static que copiará los medios de todas las aplicaciones en un único directorio para publicar en producción.

Actualización: django-staticfiles tiene become part of Django 1.3. Ahora espera que los medios de la aplicación vivan en un subdirectorio "estático /" de la aplicación, no en "media /". Y el comando de administración ahora es "colecético".

+0

Este es ahora el enfoque correcto, como el de Django 1.3. –

+1

Tenga en cuenta que https://github.com/jaddison/django-cachebuster/ proporciona una etiqueta {% static%} muy útil para Django 1.3 – Eli

2

La única aplicación que conozco que se ocupa de esto sin ninguna intervención es la más maravillosa django-debug-toolbar, aunque es discutible que esto no es un gran ejemplo, ya que es una aplicación diseñada específicamente para el modo de depuración solamente.

La forma en que se ocupa de ella es que sirve sus medios a través de Django - ver la fuente de urls.py:

url(r'^%s/m/(.*)$' % _PREFIX, 'debug_toolbar.views.debug_media'), 

En general, esta es una mala idea (que no quiere servir estática archivos a través de Django), por this comment from the documentation:

[Porción archivos estáticos a través de Django] es ineficiente y inseguro. No lo use en una configuración de producción . Use esto solo para el desarrollo .

Obviamente, la barra de herramientas de depuración de django solo se utiliza para el desarrollo, por lo que creo que su método de implementación tiene sentido, pero esta es una gran excepción.

En general, la mejor manera que conozco es crear enlaces simbólicos dondequiera que su medio esté almacenado en los medios dentro del código de su aplicación. Por ejemplo, cree una carpeta llamada media dentro de su aplicación, y luego solicite a los usuarios que instalen su aplicación que agreguen un enlace simbólico desde su directorio de medios o que copien todo.

+0

¿Y cómo debo evitar nombrar conflictos/referirme a él en mi código? Si tengo, por ejemplo, una aplicación "foo" con una carpeta multimedia y una aplicación "bar" con una carpeta multimedia, ¿cómo me refiero a la carpeta dentro de las plantillas de la aplicación, sin causar problemas? –

+1

Si su aplicación se llama 'foobar', entonces consulte sus medios usando' {{MEDIA_URL}} foobar/myawesomejs.js'. Exija a los usuarios que configuren el enlace simbólico en 'foobar' dentro de su directorio de medios. –

+0

Creo que mi respuesta a continuación (utilizando django-staticfiles) es una mejor solución completa; especialmente porque parece que algo basado en archivos estáticos puede incluirse directamente en Django 1.3. –

2

normalmente pongo medios de comunicación en./ Aplicaciones/nombreaplic/estáticos (mis aplicaciones reside en una subcarpeta aplicaciones)

entonces tengo algo similar en el host virtual en Apache:

AliasMatch ^/apps/([^/]+)/static/(.*) /home/django/projectname/apps/$1/static/$2 
<DirectoryMatch "^/home/django/projectname/apps/([^/]+)/static/*"> 
     Order deny,allow 
     Options -Indexes 
     deny from all 
     Options +FollowSymLinks 
     <FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf|txt|htm|html|json)$"> 
       allow from all 
     </FilesMatch> 
</DirectoryMatch> 

también tengo esto en mi urls.py para el servidor dev (utilice sólo para depuración):

def statics_wrapper(request, **dict): 
    from django.views import static 
    return static.serve(request, dict['path'], document_root = os.path.join(settings.BASE_DIR, 'apps', dict['app'], 'static'), show_indexes=True) 
urlpatterns += patterns('', (r'^apps/(?P<app>[^/]+)/static/(?P<path>.+)$', statics_wrapper)) 

esto es muy práctico porque url estática simplemente se asigna al sistema de archivos, por ejemplo:

http://wwww.ecample.com/apps/calendar/static/js/calendar.js reside en [BASE_DIR]/aplicaciones/calend ar// JS/estáticas calendar.js

esperanza esto ayuda

Cuestiones relacionadas