我需要从多个表中检索数据,使用动态构建的过滤器,可能会也可能不会使用来自任何表的数据。
所以说我有这个:
class Solution(models.Model):
name = models.CharField(max_length=MAX, unique=True)
# Other data
class ExportTrackingRecord(models.Model):
tracked_id = models.IntegerField()
solution = models.ForeignKey(Solution)
# Other data
然后我需要做其他事情:
def get_data(user_provided_criteria):
etr = ExportTrackingRecord.objects.filter(make_Q_object(user_provided_criteria)).select_related()
for data in etr:
s = data.solution
# do things with data from both tables
据我所知,如果我碰巧在Solution中的某个字段上进行过滤,django将进行连接,select_related
将获取这两个对象。如果我只过滤ExportTrackingRecord
中的字段,那么就没有连接,django将为QuerySet中的每个ExportTrackingRecord
生成一个新查询(可能有数千个......)
我是django的新手,但有没有合理的方法强制加入?
答案 0 :(得分:1)
select_related()
是您问题的关键。如果您不使用它并且不对相关模型的字段进行过滤,那么Django将不会进行连接,并且如果您正在访问相关模型的数据,则会对结果中的每一行进行额外查询。
如果您执行类似ExportTrackingRecord.objects.filter(...).select_related('solution')
的操作,则强制Django始终与Solution
表进行联接。
如果你需要在另一个方向上做同样的事情,通过反向外键关系你需要prefetch_related()
,多对多关系也是如此
答案 1 :(得分:0)
select_related
控制在评估QuerySet时加载到结果中的内容。无论过滤如何,它都会强制连接。
如果您未指定select_related
,那么即使您的过滤器生成带有连接的SQL查询,也不会在结果中加载父模型的字段,访问它们仍需要其他查询。