我需要有效地将大量数据从我的数据库导出到CSV,而我遇到了ManyToMany字段的问题。假设我的模型是Song
,我正在使用名为Tags
的ManyToMany字段。 Song
可能有多个Tags
,例如'摇滚','流行','悲伤'......
我想做点什么:
>>> songs_tags = Song.objects.filter(artist_id=5).values('id', 'tags__name')
然后我想得到类似的东西:
>>> songs_tags
[{'id': 1L, 'tags__name':['rock', 'pop', 'happy']}, {'id': 2L, 'tags__name': ['metal', 'angry', 'epic']}, ...]
然而,我实际得到的是:
>>> songs_tags
[{'id': 1L, 'tags__name': 'rock'}, {'id': 2L, 'tags__name': 'metal'}, ...]
为什么?
我检查过这些元素确实有多个标记,但是values()只报告其中一个,而不是全部。
注意:
我尝试重复for song in Song.objects.filter(artist_id=5)
并阅读每个song.tags.all()
。但它是斯洛伐克......
我还尝试使用prefetch_related()
(https://docs.djangoproject.com/en/1.9/ref/models/querysets/#prefetch-related)。我所做的是迭代for song in Song.objects.filter(artist_id=5).prefetch_related('tags')
并阅读每个song.tags.all()
,但它也很慢。事实上,我没有发现迭代Song.objects.filter(artist_id=5)
和Song.objects.filter(artist_id=5).prefetch_related('tags')
之间存在任何差异。
答案 0 :(得分:1)
您可以使用a raw SQL query让Postgres获取标记并将它们连接成一个字符串以获得类似的内容
[{' id':1L,'标签':'摇滚,流行,快乐']},{' id&# 39;:2L,'标签'金属,愤怒,史诗']},...]
原始SQL选择看起来像这样
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;
假设您有Django模型构建的以下表格
modulename_song
modulename_tag
modulename_song_tag