Bry*_*oso 5 django django-models
我有以下型号:
class Artist(models.Model):
name = models.CharField()
def primary_group(self):
return self.memberships.select_related('group').get(is_primary=True)
class Group(models.Model):
name = models.CharField()
members = models.ManyToManyField(Artist, through='Membership')
class Membership(models.Model):
artist = models.ForeignKey(Artist, related_name='memberships')
group = models.ForeignKey(Group)
is_primary = models.BooleanField()
Run Code Online (Sandbox Code Playgroud)
Artist并Group通过中介模式链接,Membership.艺术家只能有一个主要组,通过标记is_primary,验证等.
在我列出艺术家的模板中,我列出了除了主要组之外的基本艺术家信息,通过上述方法调用.然而,这是一个O(n)操作,我有大约160名艺术家这样做.django-debug-toolbar提供的SQL如下:
SELECT ••• FROM "people_membership"
LEFT OUTER JOIN "people_group" ON ("people_membership"."group_id" = "people_group"."id")
WHERE ("people_membership"."artist_id" = xx AND "people_membership"."is_primary" = true )
Run Code Online (Sandbox Code Playgroud)
让我补充说,对于列出的每个艺术家都会发生这种情况,所以我得到了大约160个.
考虑到我称之为模型方法,O(n)是最好的吗?或者我还能做些什么来改善这一点(缺少非规范化primary_group)?这似乎是存储在中间模型中的任何类型信息的问题,我想从源或目标调用.
您可以通过两个查询轻松完成此操作,尽管任何仇恨者都会说,但这些查询根本不重要:
artists = list(Artist.objects.all())
primary_memberships = {m.artist_id: m for m in Group.objects.filter(is_primary=True, membership__artist__in=artists).extra(select={'artist_id': '%s.artist_id' % (Membership._meta.db_table,)})}
for artist in artists:
artist.primary_membership = primary_memberships.get(artist.id)
Run Code Online (Sandbox Code Playgroud)
(附加条款可能不正确,但你明白了)
除此之外,我会改变主要功能:
if hasattr(self, '_primary_membership_cache'):
return self._primary_membership_cache
Run Code Online (Sandbox Code Playgroud)
然后,如果您附加信息,将其绑定到该变量,并使用相同的函数调用.
(我们在DISQUS各处遵循这种模式进行各种连接/奇数查询)
| 归档时间: |
|
| 查看次数: |
242 次 |
| 最近记录: |