2017-07-19 3 views
3

Hier abzufragen ist das ModellWie vorherige Artikel einer bestimmten Kriterien

class Player(models.Model): 
    name = models.CharField() 

class ShootingAttempt(models.Model): 
    player = models.ForeignKey(Player, related_name='shooting_attempts') 
    is_scored = models.BooleanField() 
    point = models.IntegerField(default=0) 
    created_at = models.DateTimeField(auto_add_now=True) 

Die Umsetzung:

jordan = Player.objects.create(name='Michael Jordan') 

attempt1 = ShootingAttempt(player=jordan, is_scored=False) 
attempt2 = ShootingAttempt(player=jordan, is_scored=False) 
attempt3 = ShootingAttempt(player=jordan, is_scored=True, point=3) 

attempt4 = ShootingAttempt(player=jordan, is_scored=False) 
attempt5 = ShootingAttempt(player=jordan, is_scored=True, point=3) 
attempt6 = ShootingAttempt(player=jordan, is_scored=True, point=3) 

Nun, wie kann ich die vorherige is_scored=False abfragen, wenn eine gegebene ShootingAttemptwo pk = 5 angenommen für Versuch5 von Spieler mit dem Namen Micheal Jordan? Dies wird das Ergebnis ergeben: [attempt4]

Mittel jordan hat 1 verpassen, bevor erfolgreich 3 Punkte in Versuch 5. graben

Wenn die ShootingAttempt gegeben, wo pk=3(attempt3) diese zurück

[attempt1, attempt2] 

Bedeutet, dass Jordan 2 Fehler hat, bevor erfolgreich die ersten 3 Punkte

graben

Und wenn pk=6 gegeben wird nichts zurück, weil es keine ist is_scored=Falsezwischen dem letztenis_scored=True und der pk=6 (attempt6)

Mittel, die jordan keine Fehl von vor dem Graben weitere 3 Punkte hat

Jeder Schießversuch kann fehlschlagen und ich möchte die letzten Fehler jedes erfolgreichen Versuches erhalten.

Gibt es irgendwelche Arbeiten?

Antwort

1

Dies sind die Schritte, die ich bevorzugen würde.

Get ID der is_scored=TrueShootingAttempt Instanz, die Sie wollen. Sprich id1

Und man könnte eine andere is_scored=TrueShootingAttempt Instanz mit .filter(id__lt=id1).aggregate(id2=Max('id')) diese erhalten kehren Sie {id2: some_id} die is_scored=True hat und unter dem id1.

id2 = ShootingAttempt.objects.all().filter(id__lt=id1).aggregate(id2=Max('id'))['id2'] 

Schließlich könnte man - .filter(id__gt=id2).filter(id__lte=id1) die mit False s kehrt queryset und letzten True.

+0

Das ist genau was ich will lass es mich testen –

+0

Sie können den Player nach Ihren Bedürfnissen filtern. – AnnShress

0

Sie können order_by in Ihrer Abfrage verwenden. Zum Beispiel:

last_false = ShootingAttempt.objects.filter(is_scored=False).order_by('-created_at')[0] 

Der Filterteil dieser Objekte mit Score „False“ wählt und danach, die sind in absteigender Modus bestellt, schließlich das erste Element der Wahl ([0]).

Sie können auch verschachtelt die Filter durch Spieler in ähnlicher Weise:

last_false = ShootingAttempt.objects.filter(player=jordan).filter(is_scored=False).order_by('-created_at')[0] 

Edit:

Wenn Sie alle die bisherigen Versuche, die die ID des Versuchs wollen, können Sie auch auswählen, von pk, mit __lt:

last_false = ShootingAttempt.objects.filter(player=jordan).filter(is_scored=False).filter(pk__lt=<shootingattempt>).order_by('-created_at') 
+0

Ich meine, ist alle vorherigen is_scored = False des angegebenen Shootingattemment –

+0

Da dies nur die letzte erhalten wird is_score = False. –

+0

Danke für die Aktualisierung Ihrer Antwort und es tut mir sehr leid, dass ich es nicht klar gemacht habe. Was ich will, ist, die vorherigen ShootingAttempten Instanzen eines bestimmten pk zu bekommen, wobei 'is_scored = False' aber nicht vor dem vorherigen' is_scored = False' von einem anderen 'is_scored = True' Datensatz –

0

Arbeit um.

attempts = ShootingAttempt.objects.filter(player=jordan)[:pk] 
n = len(attempts) 
actual_attempts = [] if attempts[n-1].is_scored == True else 
[attempts[n-1]] 
n -= 1 
while n and attempts[n-1].is_scored == False: 
    actual_attempts.append(attempts[n-1]) 
    n -= 1 
actual_attempts = actual_attempts[::-1] 
Verwandte Themen