2013-07-29 11 views
6

Mam model Django z wieloma polami (około 24), i widocznie moi użytkownicy chcieliby móc tworzyć wystąpienia tego obiektu za pomocą ładowania arkusza kalkulacyjnego zamiast ręcznego wprowadzania wszystkich danych w formy.Parse CSV z Django i csv.DictReader

Zauważyłem, że użycie wbudowanego w Pythona modułu CSV powinno sprawić, że będzie to dość proste, ale ciężko pracuję nad tym, jak go dokładnie użyć.

Zacznijmy z tym, co mam pod względem kodu:

def upload_file(request): 

    if request.method == "POST": 
    form = UploadFileForm(request.POST, request.FILES) 
    if form.is_valid(): 
     handle_files(request.FILES['file']) 
     return HttpResponseRedirect('/workflow/') 
    else: 
     print form.errors 
     print request.FILES 
     return HttpResponseRedirect('/workflow/upload') 
    else: 
    form = UploadFileForm() 
    return render(request, 'fileform.html', {'formset': form}) 

Ten akceptuje plik CSV jako przesyłanie i ręce go do handle_files do czynienia z parsowania i tworzenia obiektów. To jest metoda, z którą mam problem.

def handle_files(f): 
    reader = csv.DictReader(f, delimiter=' ', quotechar='|') 
    ... #? 

Próbowałem naśladować docs Pythona (http://docs.python.org/2/library/csv.html), ale DictReader jest bardzo słabo udokumentowane. Czy dostarczam odpowiednie argumenty w postaci csv.DictReader()? Jeśli mam, jak mogę uzyskać informacje z reader? Będę dostarczał użytkownikom szablon, więc mogę założyć, że każda kolumna pliku CSV ma przewidywalne dane. To znaczy, wiem, że kolumna A będzie zawierała dane odpowiadające polu X, a kolumna B odpowiada wartości Y itp. Jak wykonać przetwarzanie danych z czytnika, a następnie utworzyć obiekt z tymi danymi?

Zgaduję, to będzie coś takiego:

for row in reader: 
    X=row[1] 
    Y=row[2] 
    #etc 
    my_object = MyObject(x=X, y=Y) 
    my_object.save() 

Czy to daleko? Czy powinienem używać innego typu czytnika CSV?

Dzięki za pomoc, wiem, że w tym poście jest wiele pytań.

Odpowiedz

2

Niedawno zacząłem używać Django, ale wcześniej korzystałem z biblioteki csv pythona. Kiedy go używam, po prostu wykonuję następujące czynności:

import csv 
... 
reader = csv.reader(f) 
for row in reader: 
    #do something with each row 
f.close() 

Więc byłeś bardzo blisko. Indeksowanie rozpoczyna się od 0, więc jeśli chcesz pierwszy element, użyj row[0].

Więcej informacji na temat biblioteki csv znajduje się pod adresem here. Chcesz użyć separatora i innych parametrów, jeśli format pliku jest inny.

+0

Jaki jest sens DictReader wtedy? –

+0

[docs] (http://docs.python.org/2/library/csv.html#csv.DictReader) mówi, że "utworzy obiekt działający jak zwykły czytnik, ale odwzorowuje informacje odczytane w dyktafonie którego klucze są podane przez opcjonalny parametr fieldnames.Jeśli parametr fieldnames zostanie pominięty, wartości w pierwszym wierszu pliku csv będą używane jako nazwy pól. " Co brzmi, jakbyś mógł użyć wiersza ["Kolumna A"] (lub innego klucza w zależności od nazwy kolumny) –

3

Podczas tworzenia pliku csv, dodać nagłówek:

people.csv

id age height 
1 20 62 
2 22 74 
3 24 68 

def handle_files(f): 
    reader = csv.DictReader(open(f)) 
    for row in reader: 
     id=row['id'] 
     age=row['age'] 
     height=row['height'] 
     my_object = MyObject(id=id, age=age,height=height) 
     my_object.save() 
+0

@DavidCain, @srinu j: To powoduje, że "indeksy list muszą być liczbami całkowitymi, a nie str" dla mnie . Zanim otrzymam wartość typu 'id = wiersz [0]' 'age = [1]', etc ... Teraz próbuję "inteligentnie" wykryć nagłówki, ponieważ id nie zawsze może być pierwszą kolumną. Czy muszę tu zrobić coś jeszcze? – teewuane