Schnellste Weg, um das erste Objekt aus einem Quaryset in Django zu bekommen?

Oft finde ich, dass ich das erste Objekt aus einem Quaryset in Django bekommen möchte, oder es gibt keine, wenn es keine gibt. Es gibt viele Möglichkeiten, dies zu tun, was alle arbeiten. Aber ich frage mich, was der leistungsstärkste ist.

 qs = MyModel.objects.filter(blah = blah) if qs.count() > 0: return qs[0] else: return None 

Gibt es zwei Datenbankanrufe? Das scheint verschwenderisch Ist das noch schneller?

 qs = MyModel.objects.filter(blah = blah) if len(qs) > 0: return qs[0] else: return None 

Eine weitere Option wäre:

 qs = MyModel.objects.filter(blah = blah) try: return qs[0] except IndexError: return None 

Dies erzeugt einen einzigen Datenbankaufruf, was gut ist. Aber erfordert das Erstellen eines Ausnahmeobjekts viel Zeit, das ist eine sehr Gedächtnis-intensive Sache zu tun, wenn alles, was Sie wirklich brauchen, ist ein trivialer if-Test.

Wie kann ich das mit nur einem einzigen Datenbank-Aufruf und ohne Churning-Speicher mit Ausnahmeobjekten machen?

8 Solutions collect form web for “Schnellste Weg, um das erste Objekt aus einem Quaryset in Django zu bekommen?”

Django 1.6 (freigegeben am Nov 2013) führte die Bequemlichkeitsmethoden first() und last() die die resultierende Ausnahme verschlingen und None wenn das queryset keine Objekte zurückgibt.

Die richtige Antwort ist

 Entry.objects.all()[:1].get() 

Die verwendet werden können in:

 Entry.objects.filter()[:1].get() 

Du würdest es nicht wünschen, es zuerst in eine Liste zu verwandeln, denn das würde einen vollständigen Datenbankaufruf aller Datensätze erzwingen. Tu das oben und es wird nur das erste ziehen. Sie könnten sogar verwenden .order_by , um .order_by , dass Sie die erste, die Sie wollen.

.get() Sie darauf, das .get() hinzuzufügen oder Sie erhalten ein QuerySet zurück und kein Objekt.

 r = list(qs[:1]) if r: return r[0] return None 

Wenn du zuerst das erste Element bekommst, kannst du QuerySet in diese Richtung erweitern:

 class FirstQuerySet(models.query.QuerySet): def first(self): return self[0] class ManagerWithFirstQuery(models.Manager): def get_query_set(self): return FirstQuerySet(self.model) 

Modell so definieren:

 class MyModel(models.Model): objects = ManagerWithFirstQuery() 

Und benutze es so:

  first_object = MyModel.objects.filter(x=100).first() 

Nun, in Django 1.9 hast du first() Methode für querysets.

 YourModel.objects.all().first() 

Dies ist ein besserer Weg als .get() oder [0] weil es keine Ausnahme auslöst, wenn queryset leer ist. Therafore, du brauchst nicht zu überprüfen, ob es exists()

Es kann so sein

 obj = model.objects.filter(id=emp_id)[0] 

oder

 obj = model.objects.latest('id') 

Sie sollten django Methoden verwenden, wie existiert. Es gibt es für Sie, es zu benutzen.

 if qs.exists(): return qs[0] return None 

Das könnte auch funktionieren:

 def get_first_element(MyModel): my_query = MyModel.objects.all() return my_query[:1] 

Wenn es leer ist, gibt es dann eine leere Liste zurück, sonst gibt es das erste Element innerhalb einer Liste zurück.

  • Pythons Summe gegen NumPys numpy.sum
  • Warum ist es langsamer, über eine kleine Saite zu reißen als eine kleine Liste?
  • Python: Performance-Probleme mit islice
  • Warum ist numpy.array so langsam?
  • Entfernt eine Datenstruktur vs. Bauen durch Aufruf von readlines ()
  • Python mit c / fortran vergleichen
  • Bestimmen Sie den Mittelwert von 'data', wobei die höchste Anzahl von CONTINUOUS cond = True ist
  • Wie man diesen Block von Python-Code kurz und effizient macht
  • ZMQ Latenz mit PUB-SUB (langsamer Teilnehmer)
  • Warum funktioniert Pythons mmap nicht mit großen Dateien?
  • Verbessern Sie die Geschwindigkeit des Lesens und der Konvertierung von Binärdatei?
  • Python ist die beste Programmiersprache der Welt.