2011-02-02 6 views
7

Sto solo imparando Python & Django. (Grazie a tutti quelli che hanno contribuito qui - è stata una risorsa inestimabile!)Elenca il contenuto del file di directory in un modello Django

Una cosa apparentemente di base con cui sto avendo problemi è il rendering di un semplice elenco di file statici (ad esempio il contenuto di una singola directory di repository sul mio server) come elenco di collegamenti scaricabili. Se questo è sicuro o no è un'altra questione, ma supponiamo voglio farlo ...

Questo post mi ha aiutato a guidare nella giusta direzione: Python directory list returned to Django template

Questo frammento di codice emette i nomi dei file in 'myfiles' se viene eseguito da un prompt:

path= os.path.dirname(os.path.abspath(__file__)) 
myfiles = os.path.join(path, 'myfiles') 
os.chdir(myfiles) 
for files in os.listdir("."): 
    print files 

Ma come passare questi file a un modello Django e generare un elenco di collegamenti? Penso che potrei dover creare un dizionario Python/una tupla di qualche tipo per renderlo iterabile, passarlo come variabile di template e renderlo in un ciclo for?

Devo aggiungere una voce al mio file urls.py per farlo funzionare? Qualcosa come questo?

(r'^myfiles/(?P<path>.*)$', 'django.views.static.serve', {'document_root': os.path.join(os.path.dirname(__file__), 'myfiles'), 'show_indexes': True}), 

Grazie per il vostro aiuto! Sto solo imparando e non riuscivo davvero a capire come farlo dai frammenti di codice esistenti online.

EDIT: Questo è quello che ho nel mio views.py: (noterete dal '\\' che io sono in un sistema Windows)

def myfiles_page(request): 
    path = os.path.dirname(os.path.abspath(__file__)) 
    myfiles = os.path.join(path, 'myfiles\\') 
    os.chdir(myfiles) 
    x = 0 
    d = {} 
    for file in os.listdir("."): 
     d[x] = (myfiles + file) 
     x = x + 1 

    variables = RequestContext(request, { 
    'user' : request.user, 
    'filedict' : d, 
    }) 
    return render_to_response('myfiles_page.html', variables) 

Questo è come mi stava cercando di convincerlo per visualizzare in un modello: (secondo la Django documentation)

{% for key, value in filedict %} 
    {{ key }}: {{ value }} 
{% endfor %} 

Ma 'filedict' non è ancora la visualizzazione nulla nel modello. Qualche idea?

risposta

12

A qualcosa non piace, penso.

Probabilmente avrai bisogno di creare una funzione all'interno di views.py - vedi tutorial.

Questa funzione otterrà l'elenco di file da os.listdir in una lista.

Passa l'elenco nel contesto a un modello e fai il rendering_to_risposta con un modello che hai scritto - vedi tutorial.

Nel modello, l'allora qualcosa come:

{% for file in filelist %} 
    {{ file }} 
{% endfor %} 

È possibile passare nulla nel contesto di un modello. Potresti voler passare anche un elenco ampliato di file con URL: una lista di dict, in cui ogni dict ha un nome e un url. Poi il modello è:

{% for file in filelist %} 
    <a href="{{file.url}}">{{ file.name }}</a> 
{% endfor %} 

BIG FAT Avviso di protezione

Non consentire agli utenti di navigare tra i file, consentendo loro di mettere un percorso in un URL, almeno non senza davvero controllare che essi non possono fare roba come /myfiles/../../notmyfiles/secret.txt e vedere i file di altre persone semplicemente attaccando punti-punto nel percorso per andare verso l'alto.

Se non lo capisci, probabilmente non dovresti codificarlo su qualcosa di diverso da un sistema di giocattoli che non ti dispiace essere fatto a pezzi!

+7

+1 per l'avviso di sicurezza big fat. –

+0

Grazie per la risposta Spacedman - ma la parte più difficile per me è in realtà scrivere la funzione views.py per creare una lista di dts da os.listdir, dove ogni dict ha un nome e un url. So che è fondamentale, ma qualche idea lì? – fieryred

+0

Quello che ho finito con: def create_filedict (directory): \t x = 0 \t d = {} \t for file in os.listdir (directory): \t \t d [x] = (file) \t \t x = x + 1 \t return {'dict': d, 'size': x} – fieryred