如果我在管理器中添加过滤器,则对数据库的sql查询将太长,因为我的过滤器将在sql-query的开始。
在应用所有其他过滤器和更改之后,我需要在最后运行此过滤器。
当前查询集:
links = Link.objects.all().filter_deleted()
links = links.filter(linkname='linkname', left_uuid__in=all_uuids)
links = links.filter(left_type='type')
links = links.values_list('left_uuid', 'right_uuid', 'right_type')
编译队列集后的SQL查询:
SELECT "baseobj_link"."left_uuid", "baseobj_link"."right_uuid", "baseobj_link"."right_type_id"
FROM "baseobj_link"
WHERE (
"baseobj_link"."id" IN (
SELECT DISTINCT ON (U0."linkname", U0."left_uuid", U0."right_uuid") U0."id" AS Col1
FROM "baseobj_link" U0
WHERE U0."config_id" IN (2848)
ORDER BY U0."linkname" ASC, U0."left_uuid" ASC, U0."right_uuid" ASC, U0."domain_level" ASC, U0."config_id" DESC, U0."is_deleted" DESC
) AND
"baseobj_link"."is_deleted" = false AND
"baseobj_link"."linkname" = 'linkname' AND
"baseobj_link"."left_uuid" IN (
SELECT V0."uuid" AS Col1
FROM "structure_cgw" V0
WHERE (
V0."id" IN (
SELECT DISTINCT ON (U0."uuid") U0."id" AS Col1
FROM "structure_cgw" U0
WHERE U0."config_id" IN (2848)
ORDER BY U0."uuid" ASC, U0."domain_level" DESC, U0."config_id" DESC
) AND
V0."is_deleted" = false
)
) AND
"baseobj_link"."left_type_id" = 6
);
args=(2848, False, 'linkname', 2848, False, 6)
由 filter_deleted()生成的部分:
"baseobj_link"."id" IN (
SELECT DISTINCT ON (U0."linkname", U0."left_uuid", U0."right_uuid") U0."id" AS Col1
FROM "baseobj_link" U0
WHERE U0."config_id" IN (2848)
ORDER BY U0."linkname" ASC, U0."left_uuid" ASC, U0."right_uuid" ASC, U0."domain_level" ASC, U0."config_id" DESC, U0."is_deleted" DESC
)
有必要在此模型的所有查询的末尾添加此代码,因此这不是一个简单的任务。
如何最有效地解决这个问题?
答案 0 :(得分:1)
听起来像您正在尝试对子查询运行过滤器。因此,将您希望首先运行的所有代码放在子查询中。然后,在该查询结束后,在最后一个过滤器中运行您希望应用的过滤器。
会看起来像这样:
SELECT *
FROM (
SELECT "baseobj_link"."left_uuid", "baseobj_link"."right_uuid", "baseobj_link"."right_type_id"
FROM "baseobj_link"
WHERE
"baseobj_link"."is_deleted" = false AND
"baseobj_link"."linkname" = 'cgw_vhost' AND
"baseobj_link"."left_uuid" IN (
SELECT V0."uuid" AS Col1
FROM "structure_cgw" V0
WHERE (
V0."id" IN (
SELECT DISTINCT ON (U0."uuid") U0."id" AS Col1
FROM "structure_cgw" U0
WHERE U0."config_id" IN (2848)
ORDER BY U0."uuid" ASC, U0."domain_level" DESC, U0."config_id" DESC
) AND
V0."is_deleted" = false
)
AND "baseobj_link"."left_type_id" = 6
) AS t1
WHERE t1.id IN (
SELECT DISTINCT ON (U0."linkname", U0."left_uuid", U0."right_uuid") U0."id" AS Col1
FROM "baseobj_link" U0
WHERE U0."config_id" IN (2848)
ORDER BY U0."linkname" ASC, U0."left_uuid" ASC, U0."right_uuid" ASC, U0."domain_level" ASC, U0."config_id" DESC, U0."is_deleted" DESC
)
从MYSQL documentation导出表上:
派生表是在查询FROM子句范围内生成表的表达式。例如,SELECT语句FROM子句中的子查询是派生表:
SELECT ... FROM (subquery) [AS] tbl_name ...
让我知道这是怎么实现的。
答案 1 :(得分:0)
Всвоеймоделиqueryset'адополнительнохранимquerysetбезfilter_deletedипереопределяемметод_filter_or_exоlude,чтоты Такжехранимфлагфильтрации,过滤器_filter_or_exclude,过滤器已删除。