将 csv 数据导入 Django Admin 中的数据库

发布于 2024-09-28 13:25:14 字数 1365 浏览 2 评论 0原文

我尝试通过调整管理员内部的模型表单来将 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”。

我做错了什么?

I've tried to import a csv file into a database by tweaking the modelform inside the admin doing this:

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)

But i'm stuck trying to import the file i put in "file_to_import" field. Getting AttributeError in forms.py : 'function' object has no attribute 'FILES'.

What i'm doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往日情怀 2024-10-05 13:25:14

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

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/

After a long search i found an answer: Create a view inside the admin using a standard form

Form:

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()

The view:

@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)) 

The rest is part of this post:
http://web.archive.org/web/20100605043304/http://www.beardygeek.com/2010/03/adding-views-to-the-django-admin/

梦情居士 2024-10-05 13:25:14

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

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

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

Take a look at django-admin-import, it does more or less exactly what you want -- you can upload a XLS (not a CSV, but that should not matter) and lets you assign columns to model fields. Default values are also supported.

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

Additionally, it does not take away the possibility to modify individual records by hand because you don't have to replace the default model form used in the administration.

嘴硬脾气大 2024-10-05 13:25:14

save() 方法中,您无权访问请求对象 - 您可以看到它没有传入。通常您会期望有一个 NameError在那里,但我怀疑文件中的其他地方有一个名为 request() 的函数。

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

file_csv = self.cleaned_data['file_to_import']

此操作,此时您会遇到另一个问题,即当您进入 open< 时/code> - 你不能这样做,因为 file_to_import 不是服务器文件系统上的文件,它是从客户端流式传输的内存中文件。您应该能够将 file_csv 直接传递给 csv.reader

In the save() method, you don't have any access to the request object - you can see that it's not passed in. Normally you would expect to have a NameError there, but I suspect that you've got a function elsewhere in the file called request().

At the point of saving, all the relevant data should be in cleaned_data: so you should be able to do

file_csv = self.cleaned_data['file_to_import']

At that point you'll have another problem, which is when you get to open - you can't do that, as file_to_import is not a file on the server filesystem, it's an in-memory file that has been streamed from the client. You should be able to pass file_csv directly to csv.reader.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文