2010-10-20 93 views
23

he tratado de importar un archivo CSV en una base de datos mediante la deformación de la ModelForm dentro del administrador de hacer esto:Importar datos CSV en la base de datos de Django administración

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) 

Formas. 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) 

Pero estoy atrapado tratando de importar el archivo que puse en el campo "file_to_import". Obteniendo AttributeError en forms.py: el objeto 'function' no tiene ningún atributo 'FILES'.

¿Qué estoy haciendo mal?

Respuesta

16

Después de una larga búsqueda encontré una respuesta: Crear una vista en el interior del administrador mediante un formulario estándar

Forma:

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

La vista:

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

El resto forma parte de esta publicación: http://web.archive.org/web/20100605043304/http://www.beardygeek.com/2010/03/adding-views-to-the-django-admin/

+3

Enlace muerto, pero sigue vivo en archive.org: http://web.archive.org/web/20100605043304/http://www.beardygeek.com/2010/03/adding-views-to-the-django- admin/ – askvictor

+0

enlace alternativo http://note.harajuku-tech.org/adding-views-to-the-django-admin-beardy-geek – madmed

+0

Data() es alguna clase especial de herramienta django o su propio modelo de datos? – andi

1

En el método save(), no tiene acceso al objeto de solicitud; puede ver que no se ha transferido. Normalmente esperaría tener allí un NameError, pero sospecho que tiene una función en otra parte del archivo llamado request().

En el punto de ahorro, todos los datos pertinentes deben estar en cleaned_data: por lo que debe ser capaz de hacer

file_csv = self.cleaned_data['file_to_import'] 

En ese momento usted tiene otro problema, que es cuando se llega a open - No puede hacer eso, ya que file_to_import no es un archivo en el sistema de archivos del servidor, es un archivo en memoria que se ha transmitido desde el cliente. Debería poder pasar file_csv directamente al csv.reader.

+0

Tienes razón. Pero ahora tengo un AttributeError: el objeto 'DataImport' no tiene atributo 'cleaned_data'. Además, para evitar algunos problemas, agregué un "espacio en blanco = verdadero" en todos los campos del modelo. Gracias en consejo! – aldeano

3

Echa un vistazo a django-admin-import, hace más o menos exactamente lo que desea: puede cargar un XLS (no un CSV, pero eso no debería importar) y le permite asignar columnas a los campos del modelo. Los valores predeterminados también son compatibles.

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

Además, no se quitará la posibilidad de modificar los registros individuales a mano, ya que no tiene que reemplazar el modelo de formulario predeterminado que se utiliza en la administración.

+0

¿Podría dar algún ejemplo práctico de uso? – andi

Cuestiones relacionadas