2017-11-13 7 views
2

Mein Python-CSV-Import-Skript erstellt jedes Mal einen zusätzlichen leeren Eintrag im Datenbankmodell, wenn ich Daten lade. Ich habe versucht, verschiedene Wege zu arbeiten, aber ich bekomme immer noch einen leeren Eintrag plus die eigentlichen Daten werden von der CSV geladen. Hier ist, was mein Skript ist. Bitte, deine Hilfe wird sehr gut sein.CSV-Import in Django-Modelle

class CsvUploadView(LoginRequiredMixin, FormView): 
form_class = CsvAttendeeForm 
template_name = 'attendee/upload_attendee_csv.html' 
success_url = reverse_lazy('home') 

def post(self, request, *args, **kwargs): 

    form_class = self.get_form_class() 
    form = self.get_form(form_class) 
    file = request.FILES.get('file') 
    if form.is_valid(): 
     if file: 
      reader = csv.reader(file, delimiter=',') 
      next(reader) 
      attendee_instance = Attendee() 
      Attendee.objects.bulk_create(
       [Attendee(firstname=row[0], 
          surname=row[1], 
          email=row[2], 
         ) 
       for row in reader]) 

      attendee_instance.save() 

     return self.form_valid(form) 

    else: 
     return self.form_invalid(form) 

Antwort

1

Ihr Problem mit diesem (geerntet) Abschnitt ist Sparend:

attendee_instance = Attendee() 

Attendee.objects.bulk_create(
       [Attendee(firstname=row[0], 
          surname=row[1], 
          email=row[2], 
         ) 
attendee_instance.save() 

Mit dem ersten Teilnehmer_Instanz, Sie erstellen ein leeres Objekt Attendee. Sie speichern später dieses leere Objekt mit attendee_instance.save().

Die Linie in der Mitte - Attendee.objects.bulk_create... - Sie übergeben in einer einzigen Artikelliste zu bulk_create, so dass es das Objekt (mit Daten) dort erstellt. Du brauchst beides nicht.

Was Sie wollen, ist wahrscheinlich:

Attendee.objects.create(firstname=row[0], 
          surname=row[1], 
          email=row[2], 
         ) 

Sie brauchen nicht die bulk_create es sei denn, Sie mehr als ein Objekt erstellen, können Sie nur create straight-up verwenden. Entsprechend müssen Sie das Objekt nicht durch attendee_instance=Attendee() erstellen und dann die Attribute manuell ändern, wenn Sie alles auf einmal wie oben beschrieben ausführen können.

Es lohnt sich, die caveats on the limitations of bulk create notieren, besonders wenn Sie nicht Postgres verwenden, und wenn Sie auf den Punkt auch post_save und pre_save Signale zu verwenden. Die create Methode tut auslösen diese speichern Signale, so stellen Sie sicher, dass Sie die am besten für Ihren Anwendungsfall verwenden

+0

Wow! Vielen Dank, es hat wie ein Zauber funktioniert. Ich habe das Speichern der Instanz entfernt und alles funktioniert. Es sieht so aus, als ob bulk_create das Speichern der erstellten Instanz übernimmt. Tausend Dank. – sonlinux

+0

Glücklich zu helfen - und es tut tatsächlich die Rettung! Es ist erwähnenswert, dass die Einschränkungen der Massenerstellung (https://docs.djangoproject.com/en/1.11/ref/models/querysets/#bulk-create), besonders wenn Sie nicht Postgres verwenden, und Auch wenn Sie an die Verwendung von 'post_save'- und' pre_save'-Signalen kommen. Die [create] (https://docs.djangoproject.com/en/1.11/ref/models/querysets/#create) -Methode * löst diese Sicherungssignale aus, also stellen Sie sicher, dass Sie die für Sie am besten geeignete Methode verwenden Anwendungsfall - Ich habe die Antwort jetzt auch mit diesen aktualisiert. – Withnail

+0

In der Tat, so viel habe ich von Ihrer Berufsberatung gelernt. Eine weitere Sache, im selben Modell habe ich ein Feld namens ** Autor ** und es ist über einen ** ForeignKey ** mit dem Django ** User ** Modell verbunden. Ich wollte den aktuellen Benutzer instanziieren und speichern, der den Upload als Autor macht, aber ich bekomme einen Fehler von etwas wie '' 'Verletzung von Null-Constraints ... nicht erlaubt''', aber das Objekt wird erstellt und der Autor, der das ist Der aktuell angemeldete Benutzer wird in der Datenbank instanziiert. – sonlinux

1

Es sieht aus wie Sie initialisieren und eine leere Instanz neben der bulk_create

# This line shouldn't be needed 
attendee_instance = Attendee() 
Attendee.objects.bulk_create(
     [Attendee(firstname=row[0], 
      surname=row[1], 
      email=row[2], 
     ) 
     for row in reader]) 

# Nor should this line. 
attendee_instance.save() 
Verwandte Themen