2016-06-02 4 views
2

Ich habe die folgenden Modelle aufgebaut:Zählen Anzahl von Vorkommen in Fremdschlüsselbeziehungen

class Team(models.Model): 
    # stuff 

class Alliance(models.Model): 
    # an alliance is made up of 3 teams 
    teams = models.ManyToManyField(Team) 

class Match(models.Model): 
    # 2 alliances per match 
    alliances = models.ManyToManyField(Alliance) 
    # 1 winner per match 
    winner = models.ForeignKey(Alliance, related_name='winner') 

Ich versuche, welche Teams und Allianzen zu finden, die meisten Siege. Ich habe erfolgreich Allianzen bekommen durch diese Arbeit:

from collections import Counter 
def most_alliance_wins(): 
    matches = Match.objects.all() 
    count = Counter() 
    for m in matches: 
     count[m.winner] += 1 
    # Remove ties 
    del count[None] 
    return count.most_common(5) 

jedoch meine Teams gewinnt Methode wird nicht funktionieren, sagen, dass ich nicht den Manager für das Modell zugreifen können, aber ich bin nicht sicher, wo in der Code Ich versuche tatsächlich, auf den Manager zuzugreifen, also bin ich ein bisschen verloren.

from collections import Counter 
def most_team_wins(): 
    matches = Match.objects.all() 
    count = Counter() 
    for m in matches: 
     for team in m.winner.objects.all(): 
      count[team] += 1 
    return count.most_common(5) 

Jede Hilfe wäre

+1

Es könnte besser sein, die Antwort auf Ihre Frage als Antwort anstatt als Bearbeitung zu posten, um den Q/A-Stil für jemanden zu teilen, der in Zukunft dasselbe Problem haben könnte. – Pythonista

+0

Okay, ich werde das tun. – Justin

+0

Ja, ich habe ein paar Dinge für die Frage ausgelassen. An meinen bisherigen Testfällen funktioniert alles einwandfrei. – Justin

Antwort

1

Ah immens geschätzt werden, bin ich stumm. Gelöst!

Dies ist die Lösung:

def most_wins(): 
    matches = Match.objects.all() 
    count = Counter() 
    for m in matches: 
     if m.winner is None: 
      continue 
     for team in m.winner.teams.all(): 
      count[team] += 1 
    return count.most_common(5) 

ich Referenzierung m.winner.teams.all() statt m.winner.objects.all() werden sollte.

+1

Während diese Antwort funktioniert, wird es ein Datenbank-Killer sein. Beachten Sie, wie Sie mit dem Abrufen aller Match-Objekte beginnen. Wenn es Hunderttausende von Datensätzen gibt, erhalten Sie viele Daten. Zweitens beachten Sie, wie Sie eine verschachtelte Schleife haben. Und in Ihrer geschachtelten Schleife machen Sie eine verschachtelte Schleife. Eine verschachtelte Schleife ist selten die richtige Lösung zum Abrufen von Daten – e4c5

+0

Was können Sie stattdessen empfehlen? Ich werde wahrscheinlich zwischen 70-110.000 Einträge für die Match-Tabelle haben, und ich verwende MariaDB/MySQL und nicht SQLite. – Justin

+0

Post die echten Modelle und ich werde versuchen, einen Riss zu haben. – e4c5