2010-10-20 52 views
23

我試圖通過調整管理做這個裏面的ModelForm到CSV文件導入到數據庫中:導入CSV數據到數據庫中Django管理

models.py:

class Data(models.Model): 
    place = models.ForeignKey(Places) 
    time = models.DateTimeField() 
    data_1 = models.DecimalField(max_digits=3, decimal_places=1) 
    data_2 = models.DecimalField(max_digits=3, decimal_places=1) 
    data_3 = models.DecimalField(max_digits=4, decimal_places=1) 

形式。 PY:

import csv 
class DataImport(ModelForm): 
    file_to_import = forms.FileField() 

    class Meta: 
     model = Data 
     fields = ("file_to_import", "place") 

    def save(self, commit=False, *args, **kwargs): 
     form_input = DataImport() 
     self.place = self.cleaned_data['place'] 
     file_csv = request.FILES['file_to_import'] 
     datafile = open(file_csv, 'rb') 
     records = csv.reader(datafile) 
     for line in records: 
      self.time = line[1] 
      self.data_1 = line[2] 
      self.data_2 = line[3] 
      self.data_3 = line[4] 
      form_input.save() 
     datafile.close() 

Admin.py:

class DataAdmin(admin.ModelAdmin): 
    list_display = ("place", "time") 
    form = DataImport 

admin.site.register(Data, DataAdmin) 

但我卡住試圖導入我放在「file_to_import」字段的文件。在forms.py中獲取AttributeError:'function'對象沒有屬性'FILES'。

我做錯了什麼?

回答

16

經過長時間的搜尋後,我找到了答案:

class DataInput(forms.Form): 
    file = forms.FileField() 
    place = forms.ModelChoiceField(queryset=Place.objects.all()) 

    def save(self): 
     records = csv.reader(self.cleaned_data["file"]) 
     for line in records: 
      input_data = Data() 
      input_data.place = self.cleaned_data["place"] 
      input_data.time = datetime.strptime(line[1], "%m/%d/%y %H:%M:%S") 
      input_data.data_1 = line[2] 
      input_data.data_2 = line[3] 
      input_data.data_3 = line[4] 
      input_data.save() 

的觀點:

@staff_member_required 
def import(request): 
    if request.method == "POST": 
     form = DataInput(request.POST, request.FILES) 
     if form.is_valid(): 
      form.save() 
      success = True 
      context = {"form": form, "success": success} 
      return render_to_response("imported.html", context, 
      context_instance=RequestContext(request)) 
    else: 
     form = DataInput()   
     context = {"form": form} 
     return render_to_response("imported.html", context, 
     context_instance=RequestContext(request)) 

其餘部分採用標準的形式

窗體創建管理員內部的視圖本帖子的內容: http://web.archive.org/web/20100605043304/http://www.beardygeek.com/2010/03/adding-views-to-the-django-admin/

+3

鏈接已死,但在archive.org仍然存在:http://web.archive.org/web/20100605043304/http://www.beardygeek.com/2010/03/adding-views-to-the-django- admin/ – askvictor 2012-07-17 22:41:56

+0

替代鏈接http://note.harajuku-tech.org/adding-views-to-the-django-admin-beardy-geek – madmed 2012-11-28 16:20:46

+0

Data()是一些特殊的django工具類或您自己的數據模型? – andi 2014-03-19 08:25:50

1

save()方法,你不必請求對象的任何訪問 - 你可以看到,它不是在傳遞通常你會希望有一個NameError那裏,但我懷疑你已經有了一個功能。其他地方的文件名爲request()

挽救的地步,所有相關的數據應該是在cleaned_data:所以你應該能夠做到

file_csv = self.cleaned_data['file_to_import'] 

在這一點上,你就會有另外一個問題,當你到open這是 - 你不能這樣做,因爲file_to_import不是服務器文件系統上的文件,而是來自客戶端的流內存文件。您應該能夠將file_csv直接傳遞給csv.reader

+0

你說得對。但是現在我已經有了一個AttributeError:'DataImport'對象沒有'cleaned_data'屬性。另外,爲了避免一些問題,我在所有模型的字段中添加了「blank = True」。感謝您的建議! – aldeano 2010-10-23 04:43:43

3

看一看django-admin-import,它或多或少地完全符合您的需求 - 您可以上傳XLS(不是CSV,但這應該不重要),並允許您將列分配給模型字段。默認值也被支持。

http://pypi.python.org/pypi/django-admin-import/0.2.1

此外,並沒有帶走的可能性,手動修改個人記錄,因爲你不必替換管理使用的默認模型形式。

+0

你能提供一些使用的例子嗎? – andi 2014-03-19 08:28:00