class parent(models.Model):
ap=models.CharField(max_length=10)
user=models.CharField(max_length=10)
class Meta:
unique_together=(("ap","user"),)
db_table='parent'
class child(models.Model):
userkey=models.ForeignKey(parent,on_delete=models.CASCADE,db_column="ap")
pn=models.CharField(max_length=10)
st=models.CharField(max_length=10,default='Y')
def get_ap(self):
return self.ap.ap
def get_pn(self):
return self.pn
class Meta:
db_table="child"
unique_together=(('userkey','pn'),)
我们说我有ap =" apkey"然后我可以访问所有的儿童模型对象" apkey"通过以下查询。
child_obj=child.objects.filter(userkey__ap="apkey")
这也可以在不使用外键关系的情况下完成,如下所示。
parent_obj=parent.objects.get(ap="apkey")
child_obj=child.objects.filter(userkey=parent_obj)
我必须知道的是,在两种方法中执行查询时发生了多少次数据库访问。 ?
在第二个中,我们知道它访问父表一次,然后访问子表一次。因此实际上发生了两次sql查询。
第一个怎么样?
答案 0 :(得分:3)
Django查询集本质上是懒惰的。 see here in documentation。 因此,在执行第二段代码时,技术上只会发生只有一个数据库命中。
进一步阐述, 从文档中说明。
q = Entry.objects.filter(headline__startswith="What")
q = q.filter(pub_date__lte=datetime.date.today())
q = q.exclude(body_text__icontains="food")
print(q)
虽然这看起来像三个数据库命中,但事实上它只在最后一行(print(q))命中数据库一次。通常,在您“询问”它们之前,不会从数据库中获取QuerySet的结果。
对于向后关系see docs here,在运行settings.py时,会创建向后关系,并且它们在技术上也应该只进行一次命中。但我对此并不十分肯定,因为我在目前的文档中没有找到任何相关信息。
希望这会有所帮助。谢谢。
答案 1 :(得分:1)
正如@shivam所说,查询集本质上是懒惰的,只有当你要求它们时才会对它们进行评估。如果要查看正在执行的sql查询,可以使用connection
。但是您只能看到当前进程的查询。查看正在执行的查询的最佳方法是使用django-debug-tool之类的工具。
from django.db import connection
parent_obj=parent.objects.get(ap="apkey")
child_obj=child.objects.filter(userkey=parent_obj)
print(len(connection.queries))
要查看查询,您可以使用查询集的query
attribute。它包含要执行的查询
例如:
Mymodels.objects.all().query