表结构概述

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. 【未解决】对于使用Windows的IDEA进行编译的文件,但无法在Linux系统中统计代码行数的疑问

    在我学习使用Windows的IDEA的过程中,将代码文件转移到Linux虚拟机当中,但无法在Linux系统中统计代码行数. 注意:拷贝进虚拟机的文件均能编译运行. 具体过程如下: root@yogil ...

  2. JPA问题汇总

    JPATools生成的实体类对大小写敏感.如果一个数据库中大小写混乱,生成的实体类也会大小写都有.这种情况会导致HibernateSQL语句查询,每次都会查询第一个大小写字段,所以需要加映射关系.@C ...

  3. Linux 驱动——Led驱动1

    led_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/init ...

  4. 微信小程序富文本中的图片大小超出屏幕

    这个问题我在小程序社区中提的,后来有个帮我回答了这个问题,我试了一下可以. 解决办法是过滤富文本内容,给图片标签添加一个样式,限制图片的最大宽度. replace(/\<img/gi,   '& ...

  5. python 写的员工信息查询

    #!/use/bin/env pythonn#_*_ coding:utf-8 _*_import timedef Bre():    while True:        Bre_falg = ra ...

  6. 【leetcode】438. Find All Anagrams in a String

    problem 438. Find All Anagrams in a String solution1: class Solution { public: vector<int> fin ...

  7. Gym - 101201E:Enclosure (点到凸包的切线)

    题意:给点N棵树,前K棵是已经拥有的,现在可以再拥有一棵树,问形成的最大凸包面积. 思路:先求K棵树的凸包C,然后对于后面的N-K棵树,我们先判断是否在凸包内,如果不在,我们要求两个切线. 这里分类讨 ...

  8. Codeforces1062C. Banh-mi(贪心+快速幂)

    题目链接:传送门 题目: C. Banh-mi time limit per test second memory limit per test megabytes input standard in ...

  9. Python手记(二)

    1.map函数 map函数用于将指定的数据成员都使用指定函数进行处理. 比如: map(float, arr) map(square, arr) 这两个函数分别将arr中成员转换为float类型,以及 ...

  10. Excel技巧--巧用差异化插入空行

    假设有上面这一列,要求在不同城市之间插入一空行相隔开.数据少的时候可以手动操作,但数据量大时,就需要以下技巧: 1.复制该列(除去标题),并粘贴到右侧一列,但上方要隔开一个单元格B2: 2.将这两列选 ...