2016-12-13 2 views
0

ganz mit dem Titel der Frage zuzuteilen rang :)Gruppe von zwei Säulen, deutlich nach dem anderen, und um durch die Zählung

Ich bin ein Anfänger in Python & django und ich habe eine Abfrage, ich versuche zu machen

Mein (vereinfachtes) Modell ist: Benutzer, Reisen, Länder.

Der Benutzer kann viele Reisen erstellen, die er will, mit welchem ​​Land er will. Er kann auch mehrere Reisen in das gleiche Land erstellen.

Mein Ziel ist es, die Top 15 Länder mit den meisten Reisen von verschiedenen Benutzer + die Anzahl zu holen. Bedeutet, dass wenn ein Benutzer 10 Reisen in dasselbe Land erstellt hat, dies als eins betrachtet wird.

Was ich bisher erreicht habe, ist

hottest_countries = models.Event.objects.values('country')\ 
         .exclude(creator=None) \ 
         .annotate(count=Count('country'))\ 
         .distinct() \ 
         .order_by('-count')[:15] 

dies die Länder und die Zählung für jedes Land aber nicht von verschiedenen Benutzern zurückzukehren.

meinen Code Ich habe das so geändert

hottest_countries = models.Event.objects.values_list('country', flat=True) 
         .exclude(creator=None) \ 
         .annotate(count=Count('country'))\ 
         .distinct() \ 
         .order_by('-count')[:15] 

    # Getting all the creators of each country 
    creators_for_country = [models.Event.objects.values_list('creator', flat=True).filter(Q(country=country_id)).distinct() for country_id in hottest_countries] 

    # Sorting again to make sure 
    hots_events_sorted = [{"country_id": country_id, "count": len(creators_for_country[idx]), "creators": creators_for_country[idx]} for idx, country_id in enumerate(hottest_countries)] 
    hots_events_sorted.sort(key=itemgetter('count'), reverse=True) 

Es funktioniert, aber:

A. Ich denke, es ist zu kompliziert ist. und muss einfacher sein.

B. Kann sein, dass die Top 15 Länder, die ich in der ersten Abfrage abgerufen habe, nicht wirklich die richtigen sind, weil die zweite Abfrage die Anzahl der Einträge reduziert, wenn sie vom Ersteller unterschieden wird. Für Beispiel Ein Benutzer erstellte 1000 Reisen nach Kanada. Dies drückt das Land in der ersten Abfrage an die Spitze der Liste. Aber wenn wir die Liste nach Erstellern aufteilen, erhalten wir einen Eintrag. Das macht Kanada auf der Liste oder gar nicht.

Hinweis: Wenn ich mit einer bestimmten Spalt zu deutlichem habe ich versuchte DB Fehlermeldung anzeigt, dass mein db durch Spalten nicht unterscheidbar unterstützen ..

+0

Welche Datenbank verwenden Sie? – wpercy

+0

sqLite in der Entwicklung und Postgres in der Bereitstellung .. Aber ich möchte es auf beiden –

+0

arbeiten lassen Warum sollten Sie wollen, dass es auf beiden funktioniert? Sie verpassen viele der Funktionen von Postgres, indem Sie Ihren Code zwingen, mit SQLite zu arbeiten. – wpercy

Antwort

0

Falls jemand hat wie ich gekämpft, hier ist meine Lösung.

Hinzufügen distinct=True im annotate mein Problem lösen

hottest_countries = models.Event.objects.values('country')\ 
        .exclude(creator=None) \ 
        .annotate(count=Count('creator', distinct=True))\ 
        .distinct() \ 
        .order_by('-count')[:15] 
Verwandte Themen