2016-11-23 7 views
0

Ich habe Probleme bei der Filterung in django-models.Wie alle Datensätze zurückgegeben werden, aber den letzten Artikel ausschließen

Ich möchte alle Datensätze eines bestimmten animal zurückgeben, aber das letzte Element basierend auf dem letzten created_at Wert ausgeschlossen und in absteigender Reihenfolge sortiert.

Ich habe dieses Modell.

class Heat(models.Model): 

    # Fields 
    performer = models.CharField(max_length=25) 
    is_bred = models.BooleanField(default=False) 
    note = models.TextField(max_length=250, blank=True, null=True) 
    result = models.BooleanField(default=False) 

    # Relationship Fields 
    animal = models.ForeignKey(Animal, related_name='heats', on_delete=models.CASCADE) 

    created_at = models.DateTimeField(auto_now_add=True, editable=False) 
    last_updated = models.DateTimeField(auto_now=True, editable=False) 

Ich war in der Lage, das gewünschte Ergebnis durch diese rohe SQL-Skript erreicht. Aber ich möchte einen Django-Ansatz.

SELECT 
    * 
FROM 
    heat 
WHERE 
    heat.created_at != (SELECT MAX((heat.created_at)) FROM heat) 
     AND heat.animal_id = '2' ORDER BY heat.created_at DESC; 

Bitte helfen Sie.

Antwort

3

Es

Heat.objects.order_by("-created_at")[1:] 

für ein bestimmtes Tier sein wird, wird es dann sein:

Heat.objects.filter(animal_id=2).order_by("-created_at")[1:] 

wo [1:] auf einem queryset hat eine regelmäßige python slice Syntax und erzeugt den richtigen SQL-Code. (In diesem Fall wird einfach das erste/zuletzt erstellte Element entfernt)

Upd: as @schwobaseggl erwähnt, in den Kommentaren funktionieren Slices mit negativem Index nicht auf Django-Querysets. Daher werden die Objekte zuerst umgekehrt geordnet.

+1

Negative Indexierung funktioniert nicht bei Abfragegruppen! – schwobaseggl

+0

@Art, danke für deine Antwort aber schwobaseggl hatte recht auch wenn ich es auf 1 änderte noch kein gewünschtes Ergebnis. –

+0

@schwobaseggl Gut zu wissen, danke – Art

1

Ich habe gerade Ihre SQL-Abfrage in Django ORM-Code umgewandelt.

Zuerst holen Sie den maximalen created_at Wert mit aggregation und tun Sie eine exclude.

from django.db.models import Max 

heat_objects = Heat.objects.filter(
    animal_id=2 
).exclude(
    created_at=Heat.objects.all().aggregate(Max('created_at'))['created_at__max'] 
) 
+0

dieser könnte in der Zukunft hilfreich sein, können Sie eine Erklärung geben? –

+0

Ich habe dem Code gerade eine Erklärung hinzugefügt. – anupsabraham

+0

Vielen Dank, dass dies in Zukunft nützlich sein könnte. –

1

um Geld zu Rekord:

obj= Heat.objects.all().order_by('-id')[0] 

Make-Abfrage:

query = Heat.objects.filter(animal_id=2).exclude(id=obj['id']).all() 
-1

Die Abfrage wäre:

Heat.objects.all().order_by('id')[1:] 

könnten Sie setzen auch alle Filter, den Sie benötigen durch Ersetzen all()

Verwandte Themen