2016-03-29 15 views
0

Veritabanımdan bir CSV'ye çok fazla veriyi verimli bir şekilde vermem gerekiyor ve ManyToMany alanında sorun yaşıyorum. Modelimin Song olduğunu ve Tags adlı ManyToMany alanını kullanıyorum diyelim. Bir SongManyToMany alanıyla Django values ​​() yöntemi: yalnızca bir öğe döndürüyor

ben böyle bir şey yapmak istiyorum ... böyle 'kaya', 'pop', 'üzücü' gibi çeşitli Tags, olabilir:

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

Sonra bir şeyler almak istiyorum gibi:

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

Ancak, ben aslında elde ediyoruz:

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

Neden?

Bu öğelerin gerçekten birden fazla etikete sahip olduğunu kontrol ettim, ancak() değerleri() yalnızca bunlardan birini değil, bunlardan birini raporlar.

Not:

Ben for song in Song.objects.filter(artist_id=5) yineleme ve her song.tags.all() okumaya çalıştım. Ama bu,

Ayrıca prefetch_related() (https://docs.djangoproject.com/en/1.9/ref/models/querysets/#prefetch-related) kullanmayı denedim. Yaptığım şey, for song in Song.objects.filter(artist_id=5).prefetch_related('tags')'u yinelemek ve her song.tags.all()'u okumaktır, ancak aynı zamanda yavaştı. Aslında, Song.objects.filter(artist_id=5) ve Song.objects.filter(artist_id=5).prefetch_related('tags') yineleme arasında herhangi bir fark görmedim.

+0

Olası yinelenen soru http://stackoverflow.com/questions/12139923/all-the-values- -çok-çok-alan-django – trinchet

cevap

1

Bu

gibi bir şey almak için bir dizeye Postgres etiketlerini getirme izin vermedi ve onları birleştirmek için a raw SQL query kullanabilirsiniz [{ 'id': 1L, 'etiketler': 'rock, pop, mutlu'] }, { 'id': 2L, 'etiketler': 'metal, kızgın, epik']}, ...]

ham SQL sahip varsayarak bu

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; 

gibi görünecektir seçmek Sizin tarafınızdan Django model

012 tarafından oluşturulan aşağıdaki tablolar
  • Şarkı tablosu: modulename_song
  • Etiket tablosu: modulename_tag
  • ManyToMany ilişkisi tablosu: modulename_song_tag
+0

Teşekkürler! Maalesef veritabanımız Postgress üzerinde değil, MySQL'de ve string_agg() mevcut değil. Ama ham bir SQL sorgusu kullanma fikrini beğendim ve bu yöne gideceğim. – eelioss