【问题标题】:Import csv data into database in Django Admin在 Django Admin 中将 csv 数据导入数据库
【发布时间】:2011-04-27 20:09:30
【问题描述】:

我尝试通过在管理员中调整模型表单来将 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' 对象没有属性'FILES'。

我做错了什么?

【问题讨论】:

    标签: django django-models csv django-admin


    【解决方案1】:

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

    表格:

    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/

    【讨论】:

    【解决方案2】:

    看看django-admin-import,它或多或少完全符合您的要求——您可以上传 XLS(不是 CSV,但这没关系),并允许您将列分配给模型字段。还支持默认值。

    https://pypi.org/project/django-admin-import/

    此外,它不会消除手动修改单个记录的可能性,因为您不必替换管理中使用的默认模型表单。

    【讨论】:

      【解决方案3】:

      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'。另外,为了避免一些问题,我在所有模型的字段中添加了“空白=真”。感谢您的建议!
      猜你喜欢
      • 1970-01-01
      • 2012-06-29
      • 2013-04-19
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-30
      相关资源
      最近更新 更多