一. 多表的创建

  1. 一对一

    在哪个表中设置都行,但是添加数据的时候需要现在没有外键的表中添加数据

    models.OneToOneField(to="表名",to_field="id")

  2. 一对多

    在多的表中创建外键,创建完的这个是外键字段,会在类属性的基础上加_id

    models.ForeignKey(to="表名")

  3. 多对多

    mysql是在第三张表中添加两个外键

    orm中不用手动创建第三表,所以外键设置在哪个表中都行,设置完了这个属性不是表字段了,但是这个属性可以查询多对多关联关系

二. 多表的添加

  1. 一对一

    先创建被关联的,也就是没有外键的,因为不这样哪个表会关联不到数据而报错

    第一种根据对象添加

    obj = models.被关联表.objects.create(id=xxx,name="xxx")

    models.关联表.objects.create(name=xxx,外键=obj)

    第二种根据id添加

    models.关联表.objects.create(name=xxx,外键=id)

  2. 一对多

    和一对一一样,只不过一对一的那个外键多了unique的约束

  3. 多对多

    先添加数据到两个多对多的表,然后用外键属性.add()添加

    关联表.外键属性.add(1,2,3)或者add(*[1,2,3])

三. 多表的删除

  1. 一对一或者一对多

    obj.filter(id=1).delete()           delete()可以删除对象,也可以删除列表对象

  2. 多对多

    obj.get(id=1).属性.remove(*args)  指定删除被关联对象集合的某一个或多个

    obj.get(id=1).属性.clear()       清空被关联对象集合

    obj.get(id=1).属性.set([列表])      先清空再修改

四. 多表的修改

  1. 一对一或者一对多

    obj.filter(id=id).update(**kwargs)    只能修改列表对象

  2. 多对多

    obj.get(id=1).属性.set([列表])      工作原理是先清空然后再修改         

五. 多表的查询(子查询)

  多表查询的时候,如果 => 指向的是一,拿到的就是对象,=> 指向的是多,拿到的是列表对象

  1. 一对一

  正向查询 有外键属性 => 没有外键属性

    先找到要查询的那一行,然后用外键属性拿到被关联的对象

    obj.外键属性.name

  反向查询 没有外键属性 => 有外键属性

    先找到要查询的那一行,然后用表名拿到关联的对象

    obj.表名.name

  2. 多对一

  正向查询 多 => 一

    先找到要查询的那一行,然后用外键属性拿到被关联的对象

    obj.外键属性.name

  反向查询 一 => 多

    先找到要查询的那一行,然后用表名_set拿到关联的列表对象

    obj.表名_set.all()

  3. 多对多

  正向查询 有外键属性 => 没有外键属性

    先找到要查询的那一行,然后用外键属性拿到被关联的列表对象

    obj.外键属性.all()

  反向查询 没有外键属性 => 有外键属性

    先找到要查询的那一行,然后用表名_set拿到关联的列表对象

    obj.表名_set.all()

    

六. 关联管理器对象

  关联管理器对象就是查询到的对象有多个的时候

  1. 关联管理器对象的方法

    create(**kwargs)    创建对象,并将他添加到关联对象集中

    add(*agrs)       把指定的model对象(或id)添加到关联对象集中

    set([])         更新model对象的关联对象,先清空再添加

    remove(*args)     从关联对象集中删除执行的model对象

    clear()         从关联对象集中清空所有对象,前提是字段可以位null

七. 多表的查询(join连表查询)

  join连表效率更高

  1. 正向查询

    正向查询用   外键属性__   格式来连表, __后面写连表后要的属性或者外键属性(多层连表)

  2. 反向查询

    反向查询用  表名__  格式来连表,__后面写连表后要的属性或者外键属性(多层连表) 

八. 聚合查询,分组查询,F查询和Q查询

  from django.db.models import Avg,Count,Max,F,Q

  1. 聚合查询

    aggregate(*args,**kwargs)

    objects.aggregate(a=Avg("price"))  返回的是一个字典,并且赋值给a

  2. 分组查询

    annotate()    配合values分组依据,annotate来统计值

    objects.values("分组字段").annotate(c=Count("要统计的字段"))    先根据values分组依据分组,分组依据可以正向也可以反向

    objects.annotate(c=Count("统计的字段")).values("分组字段","c")  先根据id分组(每条都是一组),后面的values是获取需要的值,不是分组依据

  3. F查询

    可以对同一个models对象中的两个不同字段进行比较

    objects.update(price=F("price")+30)

  4. Q查询

    不局限于filter中逗号表示的and,Q提供了and(&) or(|) not(~),并且Q()方法必须写在前面

九.queryset的方法大全

##################################################################
# PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
################################################################## def all(self)
# 获取所有的数据对象 def filter(self, *args, **kwargs)
# 条件查询
# 条件可以是:参数,字典,Q def exclude(self, *args, **kwargs)
# 条件查询
# 条件可以是:参数,字典,Q def select_related(self, *fields)
性能相关:表之间进行join连表操作,一次性获取关联的数据。 总结:
1. select_related主要针一对一和多对一关系进行优化。
2. select_related使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能。 def prefetch_related(self, *lookups)
性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。 总结:
1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。
2. prefetch_related()的优化方式是分别查询每个表,然后用Python处理他们之间的关系。 def annotate(self, *args, **kwargs)
# 用于实现聚合group by查询 from django.db.models import Count, Avg, Max, Min, Sum v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id'))
# SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id')).filter(uid__gt=1)
# SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id',distinct=True)).filter(uid__gt=1)
# SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 def distinct(self, *field_names)
# 用于distinct去重
models.UserInfo.objects.values('nid').distinct()
# select distinct nid from userinfo 注:只有在PostgreSQL中才能使用distinct进行去重 def order_by(self, *field_names)
# 用于排序
models.UserInfo.objects.all().order_by('-id','age') def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
# 构造额外的查询条件或者映射,如:子查询 Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid']) def reverse(self):
# 倒序
models.UserInfo.objects.all().order_by('-nid').reverse()
# 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序 def defer(self, *fields):
models.UserInfo.objects.defer('username','id')

models.UserInfo.objects.filter(...).defer('username','id')
#映射中排除某列数据 def only(self, *fields):
#仅取某个表中的数据
models.UserInfo.objects.only('username','id')

models.UserInfo.objects.filter(...).only('username','id') def using(self, alias):
指定使用的数据库,参数为别名(setting中的设置) ##################################################
# PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
################################################## def raw(self, raw_query, params=None, translations=None, using=None):
# 执行原生SQL
models.UserInfo.objects.raw('select * from userinfo') # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名
models.UserInfo.objects.raw('select id as nid from 其他表') # 为原生SQL设置参数
models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,]) # 将获取的到列名转换为指定列名
name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
Person.objects.raw('SELECT * FROM some_other_table', translations=name_map) # 指定数据库
models.UserInfo.objects.raw('select * from userinfo', using="default") ################### 原生SQL ###################
from django.db import connection, connections
cursor = connection.cursor() # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
row = cursor.fetchone() # fetchall()/fetchmany(..) def values(self, *fields):
# 获取每行数据为字典格式 def values_list(self, *fields, **kwargs):
# 获取每行数据为元祖 def dates(self, field_name, kind, order='ASC'):
# 根据时间进行某一部分进行去重查找并截取指定内容
# kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
# order只能是:"ASC" "DESC"
# 并获取转换后的时间
- year : 年-01-01
- month: 年-月-01
- day : 年-月-日 models.DatePlus.objects.dates('ctime','day','DESC') def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
# 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
# kind只能是 "year", "month", "day", "hour", "minute", "second"
# order只能是:"ASC" "DESC"
# tzinfo时区对象
models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)
models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai')) """
pip3 install pytz
import pytz
pytz.all_timezones
pytz.timezone(‘Asia/Shanghai’)
""" def none(self):
# 空QuerySet对象 ####################################
# METHODS THAT DO DATABASE QUERIES #
#################################### def aggregate(self, *args, **kwargs):
# 聚合函数,获取字典类型聚合结果
from django.db.models import Count, Avg, Max, Min, Sum
result = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))
===> {'k': 3, 'n': 4} def count(self):
# 获取个数 def get(self, *args, **kwargs):
# 获取单个对象 def create(self, **kwargs):
# 创建对象 def bulk_create(self, objs, batch_size=None):
# 批量插入
# batch_size表示一次插入的个数
objs = [
models.DDD(name='r11'),
models.DDD(name='r22')
]
models.DDD.objects.bulk_create(objs, 10) def get_or_create(self, defaults=None, **kwargs):
# 如果存在,则获取,否则,创建
# defaults 指定创建时,其他字段的值
obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '','u_id': 2, 't_id': 2}) def update_or_create(self, defaults=None, **kwargs):
# 如果存在,则更新,否则,创建
# defaults 指定创建时或更新时的其他字段
obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '','u_id': 2, 't_id': 1}) def first(self):
# 获取第一个 def last(self):
# 获取最后一个 def in_bulk(self, id_list=None):
# 根据主键ID进行查找
id_list = [11,21,31]
models.DDD.objects.in_bulk(id_list) def delete(self):
# 删除 def update(self, **kwargs):
# 更新 def exists(self):
# 是否有结果

queryset方法大全

ORM创建多表以及多表的增删改查的更多相关文章

  1. 第二百七十七节,MySQL数据库-数据表、以及列的增删改查

    MySQL数据库-数据表.以及列的增删改查 1.创建一个表 CREATE(创建) TABLE(表) ENGINE(引擎) ENGINE=INNODB(引擎)还有很多类引擎,这里只是简单的提一下INNO ...

  2. django之创建第8-1个项目-数据库之增删改查/数据库数据显示在html页面

    1.为test.DB数据库预先创建下面数据 1    张三    16    2015-01-02    12    李四    17    2015-01-04    13    王五    14  ...

  3. IDEA对数据库、表、记录的(增删改查可视化操作)、数据库安全性问题的演示

    对数据库的增删改查 新增数据库 修改数据库 删除数据库 对表的增删改查 新增表 修改表 删除表 对记录的增删改查 数据库安全性问题的演示 演示脏读 ​ 一个事物里面读到了另外一个事物没有提交的数据: ...

  4. magento中Model创建以及该Model对于数据库的增删改查

    本文是按照magento英文文档照做与翻译的. Model层的实现是mvc框架的一个巨大的部分.它代表了你的应用的数据,或者说大多数应用没有数据是无用的.Magento的Model扮演着一个重要的角色 ...

  5. MySQL数据库-数据表、以及列的增删改查

    1.创建一个表 CREATE(创建) TABLE(表) ENGINE(引擎) ENGINE=INNODB(引擎)还有很多类引擎,这里只是简单的提一下INNODB引擎,INNODB引擎支持事务(回滚), ...

  6. iptables详解(2)表中规则管理(增删改查)

    我们定义了四张表:raw表.mangle表.nat表.filter表,不同的表有不同的功能 filter表用来过滤,允许哪些ip.端口访问,禁止哪些ip.端口访问,表中会有很多链 ①禁止ip地址访问我 ...

  7. Sql中常用的创建表 约束 主外键 增删改查的语句

    创建数据库 USE master; GO --日记数据库 create database DiaryBase on ( name=DiaryBase_Dat,--逻辑名称 FILENAME='c:\D ...

  8. 【hbase】——Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  9. (转)Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

  10. Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...

随机推荐

  1. 每日算法之递推排序(P1866 编号)

    兔子也是数字控:每个兔子都有自己喜欢的数字区间,找出能让所有兔子都满意的组合. 将所有兔子喜欢的序号按从小到大排序,此时如果小序号的兔子选择了一个数字,则之后的兔子只要排除排在它之前的兔子数(由于已经 ...

  2. js中的“默默的失败”

    看阮一峰的js标准教程,看到了“默默的失败”觉得很形象也很无奈, 总结一下都有哪些地方会“默默的失败” 字符串内部的单个字符无法改变和增删,这些操作会默默地失败. var s = 'hello'; d ...

  3. Django SCRF跨站点请求伪造

    使用Django发POSTt请求的时候经常会遇到Forbidden的错误,然后直接了当的方法就是去setting里面吧csrf中间件注释掉,其实csrf是django给我们提供的防护措施. CSRF就 ...

  4. Jenkins解析日志(log-parser-plugin)

    Jenkins打包机打包时产生了大量的日志,当报错时,不方便查看error日志 因为日志量太大,查看全部log的时候整个web页面会卡死,所以引用log-parser-plugin可以增加过滤条件显示 ...

  5. JDBC 心得

    还记得jdbc的及个步骤, 一是class出对象 2  链接数据库 3 SQL  pre开头的 4 允许SQL,result,exeupdate, 在这里想写的通过反射得到对象, Hibernate有 ...

  6. python+selenium页面自动化 元素定位实际遇到的各种问题(持续更新)

    1.class属性有空格  (已验证) 当classname 中存在空格的时候,直接使用find_element_by_class_name时,会显示定位失败,此时,需要将classname中的空格替 ...

  7. 初学c# -- 记录QQ键盘

    扫描进程,如果QQ启动了,开始记录键盘,别的程序都不记录.记录到e:\log.txt里面,当然也可以修改为截屏+记录发送到邮箱或客户端 进程 Process[] p = Process.GetProc ...

  8. 高性能mysql 事务笔记

    事务的四大特性原子性.一致性.隔离性.持久性, 事务隔离的四大隔离级别: READ UNCOMMITTED(未提交读), 在 read uncommitted级别,事务中的修改,及时没有提交,对其他事 ...

  9. python note 11 函数名的使用、闭包、迭代器

    1.函数名就是一个变量 def func(): print("我是一个小小的函数") a = func print(a) #输出变量存放地址 <function func a ...

  10. xmal中的渐变

    <LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset=" ...