Trato de mantener un poco esquema de nomenclatura coherente en mis plantillas HTML. I. e. index.html de principal, delete.html para eliminar la página y así sucesivamente. Pero el app_directories cargador siempre parece para cargar la plantilla de la aplicación de la primera por orden alfabético.

Hay alguna forma de comprobar siempre una coincidencia en la aplicación de llamadas del templates directorio de primera?

Ajustes pertinentes en mi settings.py:

PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))

TEMPLATE_LOADERS = (
    'django.template.loaders.app_directories.load_template_source',
    'django.template.loaders.filesystem.load_template_source',
)
TEMPLATE_DIRS = (
    os.path.join(PROJECT_PATH, 'templates'),
)

He intentado cambiando el orden de TEMPLATE_LOADERS, sin éxito.


Editar solicitado por Ashok:

Dir estructura de cada aplicación:

templates/
    index.html
    add.html
    delete.html
    create.html
models.py
test.py
admin.py
views.py

En cada aplicación views.py:

def index(request):
    # code...
    return render_to_response('index.html', locals())

def add(request):
    # code...
    return render_to_response('add.html', locals())

def delete(request):
    # code...
    return render_to_response('delete.html', locals())

def update(request):
    # code...
    return render_to_response('update.html', locals())
  • puede usted proporcionar la estructura de su ‘plantillas’ directorio y un código de ejemplo de cómo se carga/de representación de la plantilla
  • El app_directories cargador suena un poco engañoso para mí. Yo habría asumido que iba a cargar plantillas de la correcta directorio de aplicaciones como usted. Después de todo, no es el punto de una aplicación de django para ser capaz de crear separados rebanadas?
InformationsquelleAutor jmagnusson | 2010-06-22

3 Comentarios

  1. 49

    La razón de esto es que el app_directories cargador es esencialmente la misma que la adición de cada uno de la aplicación de la carpeta de plantillas para la TEMPLATE_DIRS configuración, por ejemplo, como

    TEMPLATE_DIRS = (
        os.path.join(PROJECT_PATH, 'app1', 'templates'),
        os.path.join(PROJECT_PATH, 'app2', 'template'),
        ...
        os.path.join(PROJECT_PATH, 'templates'),
    )

    El problema con esto es que, como usted ha mencionado, la index.html siempre será app1/templates/index.html en lugar de cualquier otra aplicación. La solución no es fácil, mágicamente corregir este comportamiento, sin modificar el app_directories cargador y el uso de la introspección o pasar a lo largo de la información de la aplicación, que se complica un poco. Una solución más fácil:

    • Mantener su settings.py como es
    • Agregar un subdirectorio en cada aplicación de la carpeta de plantillas con el nombre de la aplicación
    • El uso de las plantillas en las vistas como ‘app1/index.html’ o ‘app2/index.html’

    Para un ejemplo más concreto:

    project
        app1
            templates
                app1
                    index.html
                    add.html
                    ...
            models.py
            views.py
            ...
        app2
            ...

    A continuación, en los puntos de vista:

    def index(request):
        return render_to_response('app1/index.html', locals())

    Incluso se podría escribir un contenedor para automatizar anteponiendo el nombre de la aplicación para todos sus puntos de vista, e incluso que podría ser extendido el uso de la introspección, por ejemplo:

    def render(template, data=None):
        return render_to_response(__name__.split(".")[-2] + '/' + template, data)
    
    def index(request):
        return render('index.html', locals())

    El _____nombre_____.split(«.»)[-2] asume que el archivo está dentro de un paquete, por lo que se convertirá por ejemplo, ‘app1.vistas’ en ‘app1’ para anteponer el nombre de la plantilla. Esto también supone que un usuario nunca va a cambiar el nombre de tu aplicación sin cambiar el nombre de la carpeta en el directorio de plantillas, que no puede ser una suposición segura de hacer y en ese caso difícil en el código el nombre de la carpeta en el directorio de plantillas.

    • Esta es casi la única cosa que echo de menos de CakePHP 🙂 espero que agregar algún día.
    • Es una buena solución para un roto django función (es un compromiso muy fácil de extender el sistema de plantillas); pero todavía se obliga a añadir la ‘aplicación’ de la carpeta a la aplicación de la carpeta de plantillas, y «appname» podría no ser el que usted desea utilizar en su proyecto…
    • Esta es una bonita y sencilla solución, siempre y cuando no haya anidado aplicaciones… 😉
    • Esta adición de muchas plantillas no es más idiomático Django. Actualmente se pueden utilizar «‘APP_DIRS’ : True» en su lugar. En forma recursiva incluye plantilla dirs principal del proyecto
    • La configuración de "APP_DIRS": True siempre trabajo. Si el nombre de la plantilla es la misma, aún necesita un poco de prefijo para hacer la plantilla cargador para distinguirlos. Pero me pregunto si puedo crear un subdirectorio templates carpeta en la raíz, y poner todas las app de la plantilla, que podría ser una buena solución?
    • Creo que va a estar bien. Pero personalmente prefiero poner plantillas para sus aplicaciones relacionadas para evitar la confusión. Por ejemplo, si tengo 2 aplicaciones llamado «primer» y «segundo» y «change_form.html’ plantillas para cada uno, yo los pondría en ‘first/templates/admin/change_form.html’ y ‘second/templates/admin/change_form.html’. Pero, por supuesto, depende de usted. Si desea recoger en 1 carpeta que se encuentra en la raíz y luego hacerlo. Y en esa situación me habría ‘templates/first/admin/change_form.html’ y ‘templates/second/admin/change_form.html’. Creo que ambas soluciones como ok.
    • Tenemos que editar este post render_to_response método está en desuso desde la versión 2.0. ENLACE

  2. 7

    Sé que este es un hilo viejo, pero he hecho algo reutilizables, que permite más simple namespacing. Usted puede cargar la siguiente como una Plantilla Cargador. Va a encontrar appname/index.html en appname/templates/index.html.

    Gist disponible aquí: https://gist.github.com/871567

    """
    Wrapper for loading templates from "templates" directories in INSTALLED_APPS
    packages, prefixed by the appname for namespacing.
    
    This loader finds `appname/templates/index.html` when looking for something
    of the form `appname/index.html`.
    """
    
    from django.template import TemplateDoesNotExist
    from django.template.loaders.app_directories import app_template_dirs, Loader as BaseAppLoader
    
    class Loader(BaseAppLoader):
        '''
        Modified AppDirecotry Template Loader that allows namespacing templates
        with the name of their app, without requiring an extra subdirectory
        in the form of `appname/templates/appname`.
        '''
        def load_template_source(self, template_name, template_dirs=None):
            try:
                app_name, template_path = template_name.split('/', 1)
            except ValueError:
                raise TemplateDoesNotExist(template_name)
    
            if not template_dirs:
                template_dirs = (d for d in app_template_dirs if
                        d.endswith('/%s/templates' % app_name))
    
            return iter(super(Loader, self).load_template_source(template_path,
                    template_dirs))
    • Bien que funciona exactamente igual que ` django.de la plantilla.los cargadores.app_directories.Cargador de` en Django 1.5.x. Y el problema aún no resuelto.
  3. 4

    La app_loader busca plantillas dentro de sus aplicaciones en el orden que se especifica en su INSTALLED_APPS. (http://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types).

    Mi sugerencia es la de anteponer el nombre del archivo de plantilla con el nombre de la aplicación para evitar estos conflictos de nombres.

    Por ejemplo, la plantilla de directorios para app1 aspecto:

    templates/
        app1_index.html
        app1_delete.html
        app1_add.html
        app1_create.html
    • Gracias Chris ! después de un largo tiempo buscando la respuesta para mí fue – la aplicación no aparece en INSTALLED_APPS, por lo que sólo se busca en la base de las plantillas de la carpeta, no la carpeta local a la aplicación. Para mí esto es debido a mi settings.py y mi local_settings.py estaban fuera de sincronización debido a que el solo el settings.py es la versión controlada, después de un tira y actualización que había una nueva aplicación, pero mi local_settings.py sobrescribió la misma.

Dejar respuesta

Please enter your comment!
Please enter your name here