2017-08-14 1 views
2

Ich schreibe ein Skript, in dem ich jedes Vorkommen eines Werts von besuchten Websites abrufen möchte.Abrufen von nicht eindeutigen Werten aus einer Django-Abfrage

Erste ich besuchte Seiten:

sd = SessionData.objects.filter(session_id__mlsession__platform__exact=int('2')) 
result = sd.values('last_page') 

ich dann die Werte erhalten, die ich erwarte:

[{'last_page': 10L}, {'last_page': 4L}, {'last_page': 10L}] 

Damit ich die Seite mit 10L als id wollen doppelt haben das Gewicht von 4L, da es zweimal erscheint.

Ich versuche, die Werte aus der Liste zu erhalten:

wordData = KeywordData.objects.filter(page_id__in=result) 

aber dann habe ich nur eindeutige Werte erhalten:

[<KeywordData: 23>, <KeywordData: 24>, <KeywordData: 8>] 

wo mein gewünschtes Ergebnis sein würde:

[<KeywordData: 23>, <KeywordData: 24>, <KeywordData: 8>, <KeywordData: 23>, <KeywordData: 24>] 

Die einzige Möglichkeit, eine eindeutige Liste nicht zu erhalten, besteht darin, eine For-Schleife zu durchlaufen, aber das ist nicht wirklich eine Option Die Daten, mit denen ich es zu tun habe, haben Millionen von Einträgen.

Wird der Filter "__in" in Django nur für eindeutige Einträge verwendet? Gibt es einen Weg, den richtigen "Django" -Weg zu bekommen?

Vielen Dank im Voraus für Ihre Hilfe!

EDIT: Die entsprechenden Modelle:

class KeywordData(models.Model): 
    page = models.ForeignKey(Page, db_column='page_id', related_name='page_pageid', default=None) 
    site = models.ForeignKey(Page, db_column='site_id', related_name='page_siteid', default=None) 
    keywords = models.CharField(max_length=255, blank=True, null=True, default=None) 

class MLSession(models.Model): 
    session = models.ForeignKey(Session, null=True, db_column='session_id') 
    platform = models.IntegerField(choices=PLATFORM_CHOICE) 
    visitor_type = models.IntegerField(default=1) 

class SessionData(models.Model): 
    session = models.ForeignKey(Session, db_column='session_id', on_delete=models.CASCADE) 
    site = models.ForeignKey(Site, db_column='site_id', db_index=True, default=None, null=True) 
    last_page = models.ForeignKey(Page, db_column='last_page_id', default=None, null=True, related_name='session_last_page') 
    first_page = models.ForeignKey(Page, db_column='first_page_id', default=None, null=True, related_name='session_first_page') 

Die Tabellen Session und Seite sind hinsichtlich ihrer ids, nur bezeichnet, die auto-inkrementiert sind.

Ich möchte die letzte Seite der Sitzung betrachten, also nur die last_page_id einbeziehen und die Schlüsselwörter von der jeweiligen Seite abrufen. Wenn dieselbe Seite oft die letzte Seite ist, möchte ich, wie bereits erwähnt, mehr Gewicht hinzufügen.

Lassen Sie mich wissen, wenn weitere Informationen benötigt werden, und nochmals vielen Dank!

+2

Bitte zeigen Sie Ihre 'SessionData' und' KeywordData' Modelle –

+0

Ich habe sie jetzt hinzugefügt. :) –

Antwort

1

Wird der Filter "__in" in django nur für eindeutige Einträge verwendet?

Die __in Filter in Django direkt den IN Zustand in SQL, und sein Verhalten ist, wie Sie beobachtet haben.

Wenn Sie doppelte Zeilen möchten, sollten Sie Ihre Abfrage wahrscheinlich als SQL JOIN neu formatieren.Sie haben Post nicht Ihre Modelle so dass ich hier denke, gezwungen bin, aber die folgende Django Abfrage sollten Sie geben, was Sie wollen:

KeywordData.objects.filter(page__session_last_page__session_id__mlsession__platform=2) 
+0

Vielen Dank für die Antwort. Dadurch kann ich alle Schlüsselwörter aus der Sitzung abrufen, die die Plattform-Nr. 2, aber ich möchte nur die Schlüsselwörter von der letzten Seite des Flusses. Weißt du irgendeinen einfachen Weg, das zu tun? Vielen Dank! –

+0

@ HelgaSigurðardottir: Wenn Sie angeben, dass Sie auf dem Feld 'session_last_page'' JOIN' möchten, das Sie bekommen soll, was Sie wollen. Siehe meine Bearbeitung. –

+0

Das funktioniert, vielen Dank! –

0

erstellen Wörterbuch von Keywords durch die Seiten-ID eingegeben:

from collections = defaultdict 

result = sd.values_list('last_page', flat=True) 
keywords_by_page_id = defaultdict(list) 
for k in KeywordData.objects.filter(page_id__in=result): 
    keywords_by_page_id[k.page_id].append(k) 

Dann durchlaufen Sie die result, um Ihre benötigte Ausgabe zu erstellen.

out = [] 
for x in results: 
    out += keywords_by_page_id[x] 
+0

Vielen Dank für Ihre Antwort. Es ist wahr, dass die Ausgabe nicht mehr eindeutig ist, aber ich bekomme [, , ], so dass es die gleichen IDs wie die IDs der letzten Seite hat. Ich werde näher auf in_bulk schauen und schauen, ob ich eine Lösung finden kann, danke! –

+0

Oh ... 'in_bulk' wird nicht funktionieren, weil' result' eine Liste von 'page_id's ist, nicht KeywordData ids. Sie sollten in der Lage sein, es zum Laufen zu bringen, indem Sie Ihr eigenes Wörterbuch erstellen, das von 'page_id's – Alasdair

+0

Danke für alle Ihre Hilfe eingegeben wird, aber dies weist nur ein Schlüsselwort jeder page_id zu. :) Für 'page_id = 4' möchte ich' keyword_id = 8' und für 'page_id = 10' bekomme ich' keyword_id = 23, keyword_id = 24'. Mit dieser Lösung bekomme ich jedoch '{10L: , 4L: }'. So überspringt jetzt Wort IDs statt Seite IDs! Ich habe versucht, dies zu knacken, wollte aber antworten, falls Sie die Lösung für dieses spezielle Problem leicht sehen könnten. –

Verwandte Themen