我有4个通过FK建立关系的模型。
class Journal(models.Model):
name = models.CharField(max_length=255)
class Volume(models.Model):
journal = models.ForeignKey(Journal, related_name='volumes')
number = models.IntegerField()
class Issue(models.Model):
volume = models.ForeignKey(Volume, related_name='issues')
number = models.IntegerField()
class Article(models.Model):
issue = models.ForeignKey(Issue, related_name='articles')
title = models.CharField(max_length=255)
我需要一种JSON格式,如跟随结构。
journal: [
{ name: 'Volume number goes here', type: 'folder', id: 'F1',
data: [
{ name: 'Issue number goes here', type: 'folder', id: 'F1F1',
data: [
{ name: 'Article name goes here>', type: 'item', id: 'F1F1I1' },
{ name: 'Article name goes here>', type: 'item', id: 'F1F1I2' },
{ name: 'Article name goes here>', type: 'item', id: 'F1F1I3' },
]},
{ name: 'Issue number goes here', type: 'folder', id: 'F1F2',
data: [
{ name: 'Article name goes here>', type: 'item', id: 'F1F2I1' },
{ name: 'Article name goes here>', type: 'item', id: 'F1F2I2' },
{ name: 'Article name goes here>', type: 'item', id: 'F1F2I3' },
]},
]
},
{ name: 'Volume number goes here', type: 'folder', id: 'F2',
data: [
{ name: 'Issue number goes here', type: 'folder', id: 'F1F1',
data: [
{ name: 'Article name goes here>', type: 'item', id: 'F2F1I1' },
{ name: 'Article name goes here>', type: 'item', id: 'F2F1I2' },
{ name: 'Article name goes here>', type: 'item', id: 'F2F1I3' },
]},
{ name: 'Issue number goes here', type: 'folder', id: 'F1F2',
data: [
{ name: 'Article name goes here>', type: 'item', id: 'F2F2I1' },
{ name: 'Article name goes here>', type: 'item', id: 'F2F2I2' },
{ name: 'Article name goes here>', type: 'item', id: 'F2F2I3' },
]},
]
}
],
我尝试过几种东西,但它会导致数百次SQL查询(因为for循环)
有什么想法吗?
答案 0 :(得分:1)
使用select_related和prefetch_related。这些方法在Django ORM中用于执行SQL JOIN,因此您不会重复查询。
答案 1 :(得分:1)
您可以使用4个查询创建该JSON文件。您只需使用prefetch_related
。
以下是一些概念证明(对于与工作相关的查询,您必须有DEBUG=True
):
from django.db import connection
journals = Journal.objects.all().prefetch_related('volumes', 'volumes__issues', 'volumes__issues__articles')
for journal in journals:
print "%s" % journal.name
for volume in journal.volumes.all():
print " %d" % volume.number
for issue in volume.issues.all():
print " %d" % issue.number
for article in issue.articles.all():
print " %s" % article.title
print len(connection.queries)
这将打印对象的简单树和最后的查询数量,这将等于4(如果在该连接之前没有进行任何查询)。从那里创建你的JSON输出并不远。
在创建精确的JSON时,Django REST Framework可能会有所帮助。假设您已完成并嵌套所有序列化程序,使用上述查询集提供JournalSerializer
,将为数据库创建4个查询。