2010-10-20 11 views
23

j'ai essayé d'importer un fichier csv dans une base de données en modifiant légèrement le ModelForm dans l'admin faire ceci:Importer des données csv dans la base de données dans Django admin

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) 

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

Mais je suis coincé en essayant d'importer le fichier que j'ai mis dans le champ "file_to_import". Obtenir AttributeError dans forms.py: l'objet 'function' n'a aucun attribut 'FILES'.

Qu'est-ce que je fais mal?

Répondre

16

Après une longue recherche, j'ai trouvé une réponse: Créer une vue à l'intérieur de l'administration à l'aide d'un formulaire standard

Forme:

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 vue:

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

Le reste fait partie de cet article: http://web.archive.org/web/20100605043304/http://www.beardygeek.com/2010/03/adding-views-to-the-django-admin/

+3

Lien mort, mais toujours vivant sur archive.org: http://web.archive.org/web/20100605043304/http://www.beardygeek.com/2010/03/adding-views-to-the-django- admin/ – askvictor

+0

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

+0

Data() est une classe spéciale d'outils django ou votre propre modèle de données? – andi

1

Dans la méthode save(), vous n'avez aucun accès à l'objet de demande - vous pouvez voir qu'il n'est pas transmis. Normalement, vous vous attendez à avoir un NameError, mais je suppose que vous avez une fonction ailleurs dans le fichier appelé request().

Au point de sauvegarde, toutes les données pertinentes doivent être en cleaned_data: vous devriez donc être en mesure de faire

file_csv = self.cleaned_data['file_to_import'] 

À ce moment-là, vous aurez un autre problème, qui est quand vous arrivez à open - vous ne pouvez pas faire cela, car file_to_import n'est pas un fichier sur le système de fichiers du serveur, c'est un fichier en mémoire qui a été diffusé depuis le client. Vous devriez pouvoir passer directement du file_csv au csv.reader.

+0

Vous avez raison. Mais maintenant, j'ai une AttributeError: l'objet 'DataImport' n'a pas d'attribut 'nettoyé_données'. Aussi, juste pour éviter certains problèmes, j'ai ajouté un "blank = True" dans tous les champs du modèle. Merci à vous conseil! – aldeano

3

Jetez un oeil à django-admin-import, il fait plus ou moins exactement ce que vous voulez - vous pouvez télécharger un XLS (pas un fichier CSV, mais cela ne devrait pas avoir d'importance) et vous permet d'assigner des colonnes aux champs du modèle. Les valeurs par défaut sont également supportées.

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

De plus, il ne supprime pas la possibilité de modifier des enregistrements individuels à la main parce que vous ne devez pas remplacer le formulaire de modèle par défaut utilisé dans l'administration.

+0

Pourriez-vous fournir un exemple d'utilisation de travail? – andi