减少django中许多模型的查询

时间:2009-11-07 21:47:15

标签: django

编辑: 事实证明,真正的问题是 - 如何让select_related遵循我定义的m2m关系?那些是对我的系统征税的人。有什么想法吗?

我的django应用程序有两个类。第一个(Item类)描述了一个项目以及一些返回有关该项目信息的函数。第二个类(Itemlist类)获取这些项的列表,然后对它们进行一些处理以返回不同的值。我遇到的问题是从Itemlist返回一个项目列表需要大量的查询,我不确定它们来自哪里。

class Item(models.Model):

# for archiving purposes
archive_id  = models.IntegerField()
users       = models.ManyToManyField(User, through='User_item_rel',
                                     related_name='users_set')

# for many to one relationship (tags)
tag         = models.ForeignKey(Tag)
sub_tag     = models.CharField(default='',max_length=40)

name        = models.CharField(max_length=40)
purch_date  = models.DateField(default=datetime.datetime.now())
date_edited = models.DateTimeField(auto_now_add=True)
price       = models.DecimalField(max_digits=6, decimal_places=2)
buyer       = models.ManyToManyField(User, through='Buyer_item_rel',
                                     related_name='buyers_set')
comments    = models.CharField(default='',max_length=400)
house_id    = models.IntegerField()

class Meta:
    ordering = ['-purch_date']

def shortDisplayBuyers(self):
    if len(self.buyer_item_rel_set.all()) != 1:
        return "multiple buyers"
    else:
        return self.buyer_item_rel_set.all()[0].buyer.name
def listBuyers(self):
    return self.buyer_item_rel_set.all()

def listUsers(self):
    return self.user_item_rel_set.all()

def tag_name(self):
    return self.tag

def sub_tag_name(self):
    return self.sub_tag

def __unicode__(self):
    return self.name

和第二节课:

class Item_list:

def __init__(self, list = None, house_id = None, user_id = None,
             archive_id = None, houseMode = 0):
    self.list = list
    self.house_id = house_id
    self.uid = int(user_id)
    self.archive_id = archive_id
    self.gen_balancing_transactions()
    self.houseMode = houseMode

def ret_list(self):
    return self.list

因此,在构建具有大量项目的Itemlist之后,Itemlist.ret_list()最多需要对25个项目进行800次查询。我该怎么做才能解决这个问题?

3 个答案:

答案 0 :(得分:0)

尝试使用select_related

根据我提出的问题here

答案 1 :(得分:0)

Dan告诉你使用select_related是正确的。

select_related可以阅读here

它的作用是返回查询集中主对象的相同查询数据以及select_related子句中指定的模型或字段。

所以,而不是像:

这样的查询
select * from item
每次访问其中一个item_list对象时,

会跟着几个这样的查询:

select * from item_list where item_id = <one of the items for the query above>

ORM将生成如下查询:

select item.*, item_list.* 
  from item a join item_list b
 where item a.id = b.item_id

换句话说:它将为所有数据命中一次数据库。

答案 2 :(得分:0)

您可能想要使用prefetch_related

与select_related类似,但可以处理selected_related不能的关系。连接发生在python中,但是我发现这种工作比大量的查询更有效。

Related reading on the subject