表结构概述

model.py :

class Something(models.Model):
name = models.CharField(max_length=32) class UserType(models.Model):
caption = models.CharField(max_length=32)
s = models.ForeignKey('Something')
  #这个s不是字段名,字段名是something_id,这里的s作用是查询的时候用:row.s.id或row.s.name # 超级管理员,普通用户,游客,黑河
class UserInfo(models.Model):
user = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
user_type = models.ForeignKey('UserType')
# user_type_id

关系:

  • something --> usertype 一对多
  • usertype --> userinfo 一对多

表单中的数据:

something:

id name
1 something1
2 something2

usertype:

id caption something_id
1 超级管理员 1
2 普通管理员 1
3 黑客 2

userinfo:

id user pwd usertype_id
1 alex 123 1
2 eric 123 2

简要说明

Django中:

  1. 某表中foreignkey关联另一张表后,会自动在本表单中创建一个名称为另一张表的列:xxx_id
  2. 一对多创建时,foreignkey需要使用在一对多中的多的表单中

查询

userinfo_obj = UserInfo.objects.all()

结果为一个类的列表,类似:[UserInfo对象,UserInfo对象,]

以上语句会得到的数据为一个元素为查询目标表单对象的列表,所以例子中的userinfo_obj为一个queryset对象我们可以通过`print(userinfo_obj.query)来查看SQL语句.

取值

比较简单:

id = userinfo_obj[0].user.id
user = userinfo_obj[0].user.user
pwd = userinfo_obj[0].user.pwd
...

values与vlue_list

queryset = UserInfo.objects.all().values('user')
结果:
[{‘user’: 'alex'},{‘user’: 'eirc'}] ================================= queryset = UserInfo.objects.all().value_list('user')
结果:
[('alex'),('eirc')]

查询中:

  • 使用values('列名称'),结果为字典组成的列表
  • 使用value_list('列名称'),结果为元组组成的列表

所以,未来操作中,我们可以使用这两个方便的东西来遍历字典取值还是使用元组取值

一对多操作

创建数据

一般我们是来这么做的:

UserInfo.objects.create(user='cc','pwd' = '123',user_type=UserType.objects.get(id=2))

很麻烦吧,其实是两步操作了,但因为建表时有了user_type_id,所以我们可以这么搞:

UserInfo.objects.create(user='cc','pwd'='123',user_type_id=2)

很简单吧...

数据查询

单表查询:

UserInfo.objects.filter(user='alex')

反向查询

需求:查询所有用户类型等于 普通用户 的所有用户名和密码

两步操作:

uid = UserType.objects.filter(caption='普通用户') 
userinfo_obj = UserInfo.objects.filter(user_type_id=uid)

两步操作很简单,那就引出了神奇的双下划线:__

queryset = UserInfo.objcets.filter(user_type__caption='普通用户')

###结果
[UserInfo对象,UserInfo对象,UserInfo对象,]
row = queryset[0] #取到一个元素
user = row.user
password = row.pwd #取到具体信息
row.user_type.id
row.user_type.caption

总结下:

  • 一对多中,正下查询使用foreignkey 的 _id 查询:row.外键字段.外键表的字段
  • 一对多中反向查询,首先还是在在一对多中的多的表单中查询,可以使用__连接相关表中的列名去查询:row__

其实感觉__有点像关系连线的意思

queryset = UserInfo.objects.filter(user_type__caption='普通用户').values('user','pwd','user_type__caption')  

####结果 [{'user':'alex','pwd':'123','user_type__caption':'普通用户'}{'user':'eric','pwd':'123','user_type__caption':'普通用户'}]

三张表跨表操作

跟上面一样,直接用__即可

queryset = UserInfo.objects.filter(user_type__s__name='xxx')

进阶操作

获取个数:

UserInfo.objects.filter(name = 'alex').count()

大于小于,还是使用双下划线__

UserInfo.objects.filter(id__gt=2)#获取ID大于2的数据 
UserInfo.objects.filter(id__lt=5)#获取ID小余5的数据
UserInfo.objects.filter(id__gt=2,id__lt=5) #获取ID大于2小于5的数据

in:

UserInfo.objects.filter(id__in=[11,22,33])  #获取id等于11、22、33的数据 
UserInfo.objects.exclude(id__in=[11,22,33]) #not in

contains(包含):

UserInfo.objects.filter(name__contains="ven")   #获取name列中包含'ven'的数据 
UserInfo.objects.filter(name__icontains="Ven") #获取name列中包含'ven'的数据,对大小写不敏感
UserInfo.objects.exclude(name__icontains="ven") #不包含

range:

UserInfo.objects.filter(id__range=[1,10])   #范围,between and ,获取id在1到10范围中的数据

联表查询

用原生代码联表:

from django.db import connection
cursor = connection.cursor()
sql = "select sum(d.count) from t_script_detail_desc as d left join t_scripts as s on d.script_id = s.script_id where d.create_time ='%s' and s.script_area = %s" %(one,self.area)
cursor.execute(sql)
num=cursor.fetchall()

有做外键关联的:

ShareScripts.objects.filter(share_obj__script_area=self.area,share_time__range=[starttime,stoptime]).count()

没有外键关联的联表,用extra:

#2个表关联
num=OperationTask.objects.filter(task_create_time__range=[starttime,stoptime],task_area=x).extra(select={'temp_type_id':'temp_type_id'},tables=['t_operation_templet'], where=['task_temp_id = temp_id']).values('temp_type_id').annotate(c=Count('task_id')).values('temp_type_id','c')
  count = ScriptsDetailDesc.objects.extra(select={'script_id': 'script_id'}, tables=['t_scripts'],where=['t_script_detail_desc.script_id = t_scripts.script_id']).aggregate(Sum('count'))
#3个表关联
result=OperationTask.objects.filter(task_create_time__range=[starttime,stoptime]).extra(select={'temp_type_id':'temp_type_id','name':'oper_type_name'},tables=['t_operation_templet','t_operation_types'], where=['task_temp_id = temp_id','temp_type_id = t_operation_types.id']).values('temp_type_id').annotate(c=Count('task_id')).values('name','c')

没有外键关联的联表,用extra 条件搜索:

num = ScriptsDetailDesc.objects.filter(create_time=one).extra(
tables=['t_scripts'],
where=['t_script_detail_desc.script_id = t_scripts.script_id','script_area =%s'],params = [self.area]).aggregate(Sum('count'))
num = ScriptsDetail.objects.filter(update_time__startswith=one).extra(
tables=['t_scripts'],
where=['t_script_detail.script_id = t_scripts.script_id','t_scripts.script_area =%s'],params = [self.area]).count()

部分参考:https://www.cnblogs.com/ccorz/p/5864470.html

Django之model联表:一对多、跨表操作,联表查询的更多相关文章

  1. Django中多表的增删改查操作及聚合查询、F、Q查询

    一.创建表 创建四个表:书籍,出版社,作者,作者详细信息 四个表之间关系:书籍和作者多对多,作者和作者详细信息一对一,出版社和书籍一对多 创建一对一的关系:OneToOne("要绑定关系的表 ...

  2. 自定义类StyleSheet跨浏览器操作样式表中的规则

    这是群里网友地瓜提供的一个类,不熟悉样式表对象和样式规则对象的浏览器差异的可以看看 /** * Stylesheet.js: utility methods for scripting CSS sty ...

  3. 【TP3.2】跨库操作和跨域操作

    一.跨库操作:(同一服务器,不同的数据库) 假设UserModel对应的数据表在数据库user下面,而InfoModel对应的数据表在数据库info下面,那么我们只需要进行下面的设置即可. class ...

  4. SQL Server 跨服务器操作

    Ø  简介 在工作中编写 SQL 时经常会遇到跨库或跨服务器操作,比如查询时,通过 A 服务器的某张表关联 B 服务器某张表,进行连接查询.或者从另一台服务器中的数据,对当前数据库中的数据进行 CRU ...

  5. How to:Installshield判断操作系统是否为64位,并且为操作注册表进行设置

    原文:How to:Installshield判断操作系统是否为64位,并且为操作注册表进行设置 IS脚本操作注册表在64位平台下必须有特殊的设置 if (SYSINFO.bIsWow64) then ...

  6. MySQl的库操作、表操作和数据操作

    一.库操作 1.1库的增删改查 (1)系统数据库: performance_schema:用来收集数据库服务器的性能参数,记录处理查询时发生的各种事件.锁等现象 mysql:授权库,主要存储系统用户的 ...

  7. Django之model补充:一对多、跨表操作

    表结构概述 model.py : class Something(models.Model): name = models.CharField(max_length=32) class UserTyp ...

  8. django(3) 一对多跨表查询、ajax、多对多

    1.一对多跨表查询获取数据的三种形式:对象.字典.元组 例:有host与business两张表,host与business的id字段关联,business在host表中的对象名是b,  通过查询hos ...

  9. 六、Django学习之基于下划线的跨表查询

    六.Django学习之基于下划线的跨表查询 一对一 正向查询的例子为 已知用户名,查询用户的电话号码.反向查询例子反之. 正向查询 其中下划线前的表示表名,无下划线的表示的是Author表 resul ...

随机推荐

  1. jsonp 实现原理

      Jsonp原理: 首先在客户端注册一个callback, 然后把callback的名字传给服务器. 此时,服务器先生成 json 数据.然后以 javascript 语法的方式,生成一个funct ...

  2. linux command 3

    #user 相关命令 #新创建一个oracle用户,这初始属于oinstall组,且同时让他也属于dba组.useradd oracle -g oinstall -G dba #删除指定用户 –r:是 ...

  3. 源代码安装-非ROOT用户安装软件的方法

    0.    前言 如果你没有sudo权限,则很多程序是无法使用别人编译好的文件安装的. 还有时候,没有对应你的主机配置的安装包,这时候需要我们自己下载最原始的源代码,然后进行编译安装. 这样安装的程序 ...

  4. 关于delete和delete[]的区别

    在C++动态内存分配中我们常用到new和delete两种操作,new用来申请内存,delete用来释放内存.那么问题来了,我们应该用delete来释放内存还是用delete[]来释放内存呢? 为了得到 ...

  5. 《从Lucene到Elasticsearch:全文检索实战》学习笔记二

    今天我给大家讲讲分词算法 分词算法概述:词是语义的最小单位.分词对搜索引擎的作用很大,可以促进搜索引擎程序自动识别语句的含义,可以提高搜索结果的匹配度,分析的质量也将直接影响了搜索结果的精确度.分词存 ...

  6. centos安装多个tomcat

    1.参考前文安装jdk.第一个tomcat 2.安装第二个tomcat后,修改/etc/profile vi /etc/profile #tomcat1 export CATALINA_BASE=/o ...

  7. https://blog.csdn.net/doegoo/article/details/50749817

    因为使用DiscuzX3.2进行系统的整合后,因为只是想在原J2EE的系统上增加论坛功能,而且J2EE中已经有一套用户的注册认证的体系,所以不需要在Discuz的系统中去注册以及登录功能,而是通过在J ...

  8. pass

    空语句 do nothing 保证格式完整 保证语义完整 以if语句为例,在c或c++/java中: if(true) ; //do nothing else { //do something } 1 ...

  9. nginx添加一个站点

    server { listen ; server_name demo.abc.com ; root /Users/pa200318/demo.cp.com/trunk; index index.php ...

  10. Java面向对象 第5节 抽象类和接口

    一.抽象类和抽象方法 区分抽象方法和普通方法1)当一个方法被abstract修饰时,该方法成为抽象方法2)抽象类所在的类必须定义为抽象类3)抽象方法不会有具体的实现,而是在抽象类的子类中通过方法重写进 ...