在Django Admin中将csv数据导入到数据库

28
我尝试通过在管理员界面内调整模型表单的方式将CSV文件导入数据库。代码如下:
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)

Forms.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' object has no attribute 'FILES'。

我做错了什么?

3个回答

18

经过长时间搜索,我找到了一个答案:使用标准表单在管理员区域内创建视图

表单:

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
备用链接http://note.harajuku-tech.org/adding-views-to-the-django-admin-beardy-geek - madmed
Data() 是一些特殊的 Django 工具类还是你自己的数据模型? - andilabs
这是我的自有数据模型。 - aldeano
链接不可用 :'( - SalahAdDin

3
请查看 django-admin-import,它几乎完全符合您的需求——您可以上传XLS文件(不是CSV文件,但这应该没有关系),并允许您将列分配给模型字段。还支持默认值。
参考链接:https://pypi.org/project/django-admin-import/ 此外,它不会取消手动修改单个记录的可能性,因为您不必替换用于管理的默认模型表单。

1
这还能用吗? - Gokul NC

2
save()方法中,您无法访问请求对象-可以看到它没有被传递进来。通常情况下,您会期望出现NameError错误,但我怀疑您在文件的其他地方有一个名为request()的函数。

在保存时,所有相关数据都应该在cleaned_data中:因此,您应该能够执行

file_csv = self.cleaned_data['file_to_import']

到了这个时候,你会遇到另一个问题,也就是当你使用open打开文件时无法进行操作,因为file_to_import不是服务器文件系统上的文件,而是从客户端流式传输的内存中的文件。你应该可以直接将file_csv传递给csv.reader


你说得对。但现在我遇到了一个AttributeError: 'DataImport'对象没有'cleaned_data'属性的问题。另外,为了避免一些问题,我在所有模型字段中添加了"blank=True"。谢谢! - aldeano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接