2012-03-24 35 views
135

Recientemente actualicé Django de v1.3.1 a v1.4.Usando os.path de Python, ¿cómo puedo subir un directorio?

En mi viejo settings.py que tienen

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname(__file__), 'templates').replace('\\', '/'), 
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 
    # Always use forward slashes, even on Windows. 
    # Don't forget to use absolute paths, not relative paths. 
) 

Esto apuntará a /Users/hobbes3/Sites/mysite/templates, pero because Django v1.4 moved the project folder to the same level as the app folders, mi archivo está ahora en settings.py/Users/hobbes3/Sites/mysite/mysite/ en lugar de /Users/hobbes3/Sites/mysite/.

Así que en realidad mi pregunta ahora es doble:

  1. ¿Cómo se utiliza os.path mirar un directorio de un nivel por encima de __file__. En otras palabras, quiero /Users/hobbes3/Sites/mysite/mysite/settings.py para encontrar /Users/hobbes3/Sites/mysite/templates usando rutas relativas.
  2. ¿Debo ser de mantenimiento de la carpeta template (que tiene plantillas cruzada de aplicaciones, como admin, registration, etc.) a nivel de proyecto o al /User/hobbes3/Sites/mysite/User/hobbes3/Sites/mysite/mysite?
+0

¿No puedes usar 'os' en' cd' en '../ mysite'? O cualquiera que sea el comando que desee – prelic

+0

@prelic Hmm? No entiendo. Estoy tratando de evitar la codificación de la ruta, porque utilizo el mismo 'settings.py' en varios servidores. La única diferencia podría ser las credenciales de la base de datos. Estaba leyendo la documentación ['os.path'] (http://docs.python.org/library/os.path.html) pero no pude encontrar un comando que te permita subir un directorio. Me gusta 'cd ..'. – hobbes3

+1

@ hobbes3 Puede simplemente 'os.path.join (os.path.dirname (__file__), '..')' '..' significa _el directorio de arriba_ en todo el sistema de archivos, no solo cuando se pasa a' cd'. –

Respuesta

173
os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'templates')) 

Por lo que en la carpeta de plantillas debe ir, no sé desde Django 1.4 acaba de salir y no he mirado todavía. Probablemente deberías hacer otra pregunta sobre SE para resolver ese problema.

También puede usar normpath para limpiar la ruta, en lugar de abspath. Sin embargo, en esta situación, Django espera una ruta absoluta en lugar de una ruta relativa.

Para compatibilidad con plataformas cruzadas, use os.pardir en lugar de '..'.

+3

¿Es una mala idea usar '..' o algo así? ¿Por qué esta respuesta obtiene menos votos? – hobbes3

+1

No sé por qué está recibiendo menos votos, pero es lo que siempre he usado. Incluso está definido en el ejemplo de ['normpath'] (http://docs.python.org/library/os.path.html#os.path.normpath). Además, atravesará los enlaces simbólicos de manera adecuada. – forivall

+0

Bueno, me gusta la simplicidad! ¿Por qué el 'abspath' sin embargo? No lo usé antes y todavía funcionaba en 'settings.py'. – hobbes3

51

Para obtener la carpeta de un archivo sólo tiene que utilizar:

os.path.dirname(path) 

Para obtener una carpeta de hasta sólo tiene que utilizar os.path.dirname nuevo

os.path.dirname(os.path.dirname(path)) 

Es posible que desee comprobar si __file__ es un enlace simbólico:

if os.path.islink(__file__): path = os.readlink (__file__) 
+6

¿Hay alguna manera de subir las carpetas 'n' sin tener que llamar' os.path.dirname' 'n' veces? –

12

Quiere exactamente esto:

BASE_DIR = os.path.join(os.path.dirname(__file__), '..') 
6
from os.path import dirname, realpath, join 
join(dirname(realpath(dirname(__file__))), 'templates') 

Actualización:

Si le sucede a "copiar" settings.py través de enlaces simbólicos, la respuesta de @ forivall es mejor:

~user/ 
    project1/ 
     mysite/ 
      settings.py 
     templates/ 
      wrong.html 

    project2/ 
     mysite/ 
      settings.py -> ~user/project1/settings.py 
     templates/ 
      right.html 

El método anterior se 'ver' wrong.html mientras El método de @ forivall verá right.html

En ausencia de enlaces simbólicos, las dos respuestas son idénticas.

+0

¿Hay algún problema con este enfoque? Funciona bien y se ve bien, pero un poco hackish;) – Gricha

+0

Es ligeramente diferente de la respuesta aceptada en la forma en que trata los enlaces. Son idénticos de lo contrario. –

2

Para un paranoico como yo, prefiero éste

TEMPLATE_DIRS = (
    __file__.rsplit('/', 2)[0] + '/templates', 
) 
+6

quizás en lugar de ''/'' deberías usar 'os.sep' – djhaskin987

5

En lo personal, me gustaría ir para el enfoque de la función

def get_parent_dir(directory): 
    import os 
    return os.path.dirname(directory) 

current_dirs_parent = get_parent_dir(os.getcwd()) 
4

Creo que lo más fácil es sólo para nombredir reutilización() para que pueda llamar

os.path.dirname(os.path.dirname(__file__)) 

si presenta está en/Users/hobbes3/Sitios/mysite/templates/method.py

Esto devolverá "/ Usuarios/hobbes3/Sitios/mysite"

3

Esto podría ser útil para otros casos en los que desea ir carpetas x arriba. Simplemente ejecute walk_up_folder(path, 6) para abrir 6 carpetas.

def walk_up_folder(path, depth=1): 
    _cur_depth = 1   
    while _cur_depth < depth: 
     path = os.path.dirname(path) 
     _cur_depth += 1 
    return path 
Cuestiones relacionadas