2016-03-29 3 views
0

Ich muss eine Menge Daten aus meiner Datenbank effizient in eine CSV exportieren, und ich habe ein Problem mit einem ManyToMany-Feld. Nehmen wir an, mein Modell ist Song und ich verwende ein ManyToMany-Feld namens Tags. Ein Song kann mehrere Tags haben, wie zum Beispiel ‚Rock‘, ‚Pop‘, ‚traurig‘ ...Django values ​​() -Methode mit ManyToMany-Feld: Es gibt nur ein Element zurück

ich, wie etwas tun möchte:

>>> songs_tags = Song.objects.filter(artist_id=5).values('id', 'tags__name') 

Und dann würde ich gerne etwas bekommen wie:

>>> songs_tags 
[{'id': 1L, 'tags__name':['rock', 'pop', 'happy']}, {'id': 2L, 'tags__name': ['metal', 'angry', 'epic']}, ...] 

aber was ich eigentlich ist:

>>> songs_tags 
[{'id': 1L, 'tags__name': 'rock'}, {'id': 2L, 'tags__name': 'metal'}, ...] 

Warum?

Ich habe überprüft, dass diese Elemente in der Tat mehr als ein Tag haben, aber Werte() nur eine von ihnen, anstatt alle von ihnen.

Hinweis:

Ich versuchte for song in Song.objects.filter(artist_id=5) zu iterieren und jede song.tags.all() zu lesen. Aber es ist sloow ...

Ich habe auch versucht, prefetch_related() (https://docs.djangoproject.com/en/1.9/ref/models/querysets/#prefetch-related) zu verwenden. Was ich getan habe ist, for song in Song.objects.filter(artist_id=5).prefetch_related('tags') zu iterieren und jedes song.tags.all() zu lesen, aber es war auch langsam. Tatsächlich habe ich keinen Unterschied zwischen der Iteration Song.objects.filter(artist_id=5) und Song.objects.filter(artist_id=5).prefetch_related('tags') bemerkt.

+0

Mögliche duplizierte Frage http://stackoverflow.com/questions/12139923/all-the-values- von-der-vielen-zu-vielen-feld-django – trinchet

Antwort

1

Sie könnten a raw SQL query verwenden, um Postgres zu lassen die Tags holen und sie in einen String verketten so etwas wie dieses

zu bekommen [{ 'id': 1L, 'Tags': 'rock, pop, glücklich'] }, { 'id': 2L 'Tags': 'Metall, wütend, episch']}, ...]

Die rohen SQL wie dies

aussehen wählen würde
SELECT modulename_song.name AS name, 
     string_agg(modulename_tag.name, ', ') AS tags 
FROM modulename_song_tag 
INNER JOIN modulename_song ON song_id=modulename_song.id 
INNER JOIN modulename_tag ON tag_id=modulename_tag.id 
WHERE song_id IN (
    SELECT id FROM modulename_song 
    WHERE artist_id=5) 
GROUP BY modulename_song.id; 

vorausgesetzt, Sie haben die folgenden Tabellen von Ihnen gebaut Django Modell

  • Lied Tabelle: modulename_song
  • Tag Tisch: modulename_tag
  • ManyToMany Beziehungstabelle: modulename_song_tag
+0

Danke! Leider ist unsere Datenbank nicht auf Postgress, sondern in MySQL und string_agg() ist nicht verfügbar. Aber ich mag die Idee, eine rohe SQL-Abfrage zu verwenden, und ich werde in diese Richtung gehen. – eelioss

Verwandte Themen