我在 Django 视图中这样做:
def by_gear(gear):
types = {
'imaging_telescopes': Telescope,
'guiding_telescopes': Telescope,
'mounts': Mount,
'imaging_cameras': Camera,
'guiding_cameras': Camera,
'focal_reducers': FocalReducer,
'software': Software,
'filters': Filter,
'accessories': Accessory,
}
filters = reduce(operator.or_, [Q(**{'%s__gear_ptr__pk' % t: gear.pk}) for t in types])
images = Image.objects.filter(filters).distinct()
return images
那是因为我有一个装备,但我不知道它是什么装备(望远镜、相机等)。这是一个基本模型。
所以我用它来判断所有的可能性reduce
。由于 Gear 的所有子类(也是 Django 模型)都pk
与基类 Gear 共享,我可以这样做。我知道它的可读性不是很好,我也没有解释得太清楚,但是如果你看一下下面生成的 SQL,就会清楚。
我正在尝试获取使用该设备(Gear)拍摄的所有图像,因此请查看它pk
是否在image__telescopes
、image__imaging_cameras
等中。
然而,这最终产生了这个 SQL:
SELECT COUNT(DISTINCT "astrobin_image"."id") FROM "astrobin_image"
LEFT OUTER JOIN "astrobin_image_imaging_telescopes"
ON ("astrobin_image"."id" = "astrobin_image_imaging_telescopes"."image_id")
LEFT OUTER JOIN "astrobin_image_guiding_telescopes"
ON ("astrobin_image"."id" = "astrobin_image_guiding_telescopes"."image_id")
LEFT OUTER JOIN "astrobin_image_software"
ON ("astrobin_image"."id" = "astrobin_image_software"."image_id")
LEFT OUTER JOIN "astrobin_image_filters"
ON ("astrobin_image"."id" = "astrobin_image_filters"."image_id")
LEFT OUTER JOIN "astrobin_image_imaging_cameras"
ON ("astrobin_image"."id" = "astrobin_image_imaging_cameras"."image_id")
LEFT OUTER JOIN "astrobin_image_mounts"
ON ("astrobin_image"."id" = "astrobin_image_mounts"."image_id")
LEFT OUTER JOIN "astrobin_image_focal_reducers"
ON ("astrobin_image"."id" = "astrobin_image_focal_reducers"."image_id")
LEFT OUTER JOIN "astrobin_image_accessories"
ON ("astrobin_image"."id" = "astrobin_image_accessories"."image_id")
LEFT OUTER JOIN "astrobin_image_guiding_cameras"
ON ("astrobin_image"."id" = "astrobin_image_guiding_cameras"."image_id")
WHERE ("astrobin_image_imaging_telescopes"."telescope_id" = 4723
OR "astrobin_image_guiding_telescopes"."telescope_id" = 4723
OR "astrobin_image_software"."software_id" = 4723
OR "astrobin_image_filters"."filter_id" = 4723
OR "astrobin_image_imaging_cameras"."camera_id" = 4723
OR "astrobin_image_mounts"."mount_id" = 4723
OR "astrobin_image_focal_reducers"."focalreducer_id" = 4723
OR "astrobin_image_accessories"."accessory_id" = 4723
OR "astrobin_image_guiding_cameras"."camera_id" = 4723 )
所以这个查询需要 2 秒以上......你能建议一种方法来改善这个混乱吗?