Импорт данных CSV в базу данных в Django Admin - PullRequest
23 голосов
/ 20 октября 2010

Я попытался импортировать 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".Получение AttributeError в forms.py: у объекта 'function' нет атрибута 'FILES'.

Что я делаю не так?

Ответы [ 3 ]

17 голосов
/ 04 ноября 2010

После долгих поисков я нашел ответ: создать представление внутри админа, используя стандартную форму

Форма:

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 голосов
/ 18 сентября 2012

Взгляните на django-admin-import, он делает более или менее точно то, что вы хотите - вы можете загрузить XLS (не CSV, но это не должно иметь значения) и позволяет назначать столбцы для полей модели.Также поддерживаются значения по умолчанию.

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

Кроме того, это не лишает возможности изменять отдельные записи вручную, поскольку вам не нужно заменять форму модели по умолчанию, используемую вадминистрация.

1 голос
/ 22 октября 2010

В методе save() у вас нет доступа к объекту запроса - вы можете видеть, что он не передан внутрь. Обычно вы ожидаете, что там будет NameError, но я подозреваю, что вы есть функция в другом месте файла с именем request().

В момент сохранения все соответствующие данные должны быть в cleaned_data: так что вы должны быть в состоянии сделать

file_csv = self.cleaned_data['file_to_import']

В этот момент у вас возникнет другая проблема, когда вы доберетесь до open - вы не сможете этого сделать, поскольку file_to_import не является файлом в файловой системе сервера, это файл в памяти, который был передан от клиента. Вы должны быть в состоянии передать file_csv напрямую csv.reader.

...