django如何跨表查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django如何跨表查询相关的知识,希望对你有一定的参考价值。

场景是这样:一个泵房表包含所有泵房,一个巡检表中包含已巡检的泵房,要查询未巡检的泵房,怎么写语句?models.py和views.py如下图在views.py中查询未巡检泵房的语句怎么写??
没获得到帮助
看了两天资料,终于找到方法,
使用字段查询in
a4=Xunjian.objects.values('bengfang')
a3=Bengfang.objects.exclude(id__in=a4).values('name')
print(a3)
可看到未巡检的泵房。
in的用法可百度刘江的博客和教程,在‘第一章,模型层’中的‘字段查询参数和聚合函数’

1、 表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称  
2、id 字段是自动添加的
3、对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
4、这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
5、定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
6、外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
参考技术A

    用NOT EXISTS

SELECT * FROM bengfang WHERE NOT EXISTS(SELECT 1 FROM xunjian WHERE bengfang.id=xunjian.id)

Django对EXISTS语句的支持并不好,生成的查询语句往往包含冗余,不是我们想要的,因此这里最好用RAW SQL:

Bengfang.objects.extra(where=[
    'NOT EXISTS(SELECT 1 FROM "xunjian" WHERE "bengfang"."id"="xunjian"."bengfang_id")'.format(
        bengfang=Bengfang._meta.db_table,
        xunjian=Xunjian._meta.db_table
    )])

2.用LEFT OUTER JOIN

SELECT * FROM bengfang LEFT OUTER JOIN xunjian ON bengfang.id=xunjian.id WHERE xunjian.id=NULL

这个情况下需要双方存在外键关系,也就是Xunjian模型中需要有一个属性是Bengfang的外键,比如bengfang = models.ForeignKey('Bengfang', related_name='xunjian')

那么对应的ORM语句是:

Bengfang.objects.filter(xunjian=None)

用到了反向引用,查询语句非常简单,但是效率要比NOT EXISTS低一些。

3.用NOT IN

SELECT * FROM bengfang WHERE id NOT IN(SELECT bengfang_id FROM xunjian)

Bengfang.objects.exclude(pk__in=Xunjian.object.values('bengfang_id'))

要注意的是NOT IN是没有索引的,当表较大的时候NOT IN的效率是要远远低于NOT EXISTS的,因此从性能上讲尽量不要去用NOT IN。

本回答被提问者采纳

以上是关于django如何跨表查询的主要内容,如果未能解决你的问题,请参考以下文章

Django之跨表查询——正反向查询(ForeignKey)

django中的跨表查询梳理

Django之跨表查询——正反向查询(ManyToManyField)

Django 补充ORM跨表查询补充

Django_基于双下划线——跨表查询

Django学习第7篇:Django之ORM跨表操作(聚合查询,分组查询,F和Q查询等)