一、单表查询API汇总

<1> all():                 查询所有结果

<2> filter(**kwargs):      它包含了与所给筛选条件相匹配的对象

<3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。

<4> exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象

<5> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列

<6> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

<7> order_by(*field):      对查询结果排序

<8> reverse():             对查询结果反向排序

<9> distinct():            从返回结果中剔除重复纪录,配合values和values_list使用

<10> count():              返回数据库中匹配查询(QuerySet)的对象数量。

<11> first():              返回第一条记录

<12> last():               返回最后一条记录

<13> exists():             如果QuerySet包含数据,就返回True,否则返回False

注意:一定区分Object与QuerySet的区别 !!!

QuerySet有update方法而Object默认没有。

单表查询之神奇的双下划线

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in models.Tb1.objects.filter(name__contains="ven") # 获取name字段包含"ven"的
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感 models.Tb1.objects.filter(id__range=[1, 3]) # id范围是1到3的,等价于SQL的bettwen and 类似的还有:startswith,istartswith, endswith, iendswith  date字段还可以:
models.Class.objects.filter(first_day__year=2017)

备注:

在Django的日志设置中,配置上一个名为django.db.backends的logger实例即可查看翻译后的SQL语句。

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}

Django项目完整版LOGGING配置:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
'[%(levelname)s][%(message)s]'
},
'simple': {
'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
},
'collect': {
'format': '%(message)s'
}
},
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'], # 只有在Django debug为True时才在屏幕打印日志
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'default': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"), # 日志文件
'maxBytes': 1024 * 1024 * 50, # 日志大小 50M
'backupCount': 3,
'formatter': 'standard',
'encoding': 'utf-8',
},
'error': {
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "xxx_err.log"), # 日志文件
'maxBytes': 1024 * 1024 * 50, # 日志大小 50M
'backupCount': 5,
'formatter': 'standard',
'encoding': 'utf-8',
},
'collect': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,自动切
'filename': os.path.join(BASE_LOG_DIR, "xxx_collect.log"),
'maxBytes': 1024 * 1024 * 50, # 日志大小 50M
'backupCount': 5,
'formatter': 'collect',
'encoding': "utf-8"
}
},
'loggers': {
# 默认的logger应用如下配置
'': {
'handlers': ['default', 'console', 'error'], # 上线之后可以把'console'移除
'level': 'DEBUG',
'propagate': True,
},
# 名为 'collect'的logger还单独处理
'collect': {
'handlers': ['console', 'collect'],
'level': 'INFO',
}
},
}

Django项目常用LOGGING配置

二、基于对象的跨表查询

一对多查询(班级表和学生表)

正向查询(由学生表查询班级表)

查询学生的班级信息

>>> student_obj = models.Student.objects.first()
>>> student_obj.cid # 通过model类中的属性查找到对应的外键数据对象
<Class: Class object>
>>> student_obj.cid.cname
'1班'
>>> student_obj.cid_id # 获取实际外键的值
1

反向查询(由班级表查询学生表)

查询班级的学生信息

>>> class_obj = models.Class.objects.first()  # 获取第一个班级对象
>>> class_obj.student_set.all() # 通过表名_set反向查询出所有的学生
<QuerySet [<Student: Student object>, <Student: Student object>]>

注意:

如果不在外键的字段中设置related_name的话,默认就用表名_set。

如果设置了related_name="students",反向查询时可直接使用students进行反向查询。

>>> class_obj.students.all() 

一对一查询

表结构设计

class Student(models.Model):
sname = models.CharField(max_length=32, verbose_name="学生姓名")
the_class = models.ForeignKey(to=Class, to_field="id", on_delete=models.CASCADE, related_name="students")
detail = models.OneToOneField(to="StudentDetail", null=True) class StudentDetail(models.Model):
height = models.PositiveIntegerField()
weight = models.PositiveIntegerField()
email = models.EmailField()

正向查询(由学生信息表查询学生详情表)

>>> student_obj = models.Student.objects.first()
>>> student_obj.detail.email
'1@1.com'

反向查询(由学生详情表反向查询学生信息表)

>>> detail_obj = models.StudentDetail.objects.get(id=1)
>>> detail_obj.student.sname
'a'

三、多对多关系

三种方式创建多对多外键方式及其优缺点

通过外键创建

class Class(models.Model):
id = models.AutoField(primary_key=True) # 主键
cname = models.CharField(max_length=32) # 班级名称
first_day = models.DateField() # 开班时间 class Teacher(models.Model):
tname = models.CharField(max_length=32) # 自定义第三张表,通过外键关联上面两张表
class Teacher2Class(models.Model):
teacher = models.ForeignKey(to="Teacher")
the_class = models.ForeignKey(to="Class") class Meta:
unique_together = ("teacher", "the_class")

通过ManyToManyField创建

class Class(models.Model):
id = models.AutoField(primary_key=True) # 主键
cname = models.CharField(max_length=32) # 班级名称
first_day = models.DateField() # 开班时间 class Teacher(models.Model):
tname = models.CharField(max_length=32)
# 通过ManyToManyField自动创建第三张表
cid = models.ManyToManyField(to="Class", related_name="teachers")

通过外键和ManyToManyField创建

class Class(models.Model):
id = models.AutoField(primary_key=True) # 主键
cname = models.CharField(max_length=32) # 班级名称
first_day = models.DateField() # 开班时间 class Teacher(models.Model):
tname = models.CharField(max_length=32)
# 通过ManyToManyField和手动创建第三张表
cid = models.ManyToManyField(to="Class", through="Teacher2Class", through_fields=("teacher", "the_class")) class Teacher2Class(models.Model):
teacher = models.ForeignKey(to="Teacher")
the_class = models.ForeignKey(to="Class") class Meta:
unique_together = ("teacher", "the_class")

四、多对多操作

正向查询(由老师表查询班级表)

>>> teacher_obj = models.Teacher.objects.first()
>>> teacher_obj.cid.all() # 查询该老师授课的所有班级
<QuerySet [<Class: Class object>, <Class: Class object>]>

反向查询(由班级表反向查询老师表)

>>> class_obj = models.Class.objects.first()
>>> class_obj.teachers.all() # 此处用到的是related_name,如果不设置的话就用默认的表名_set
<QuerySet [<Teacher: Teacher object>, <Teacher: Teacher object>, <Teacher: Teacher object>]>

五、class RelatedManager

"关联管理器"是在一对多或者多对多的关联上下文中使用的管理器。

它存在于下面两种情况:

  1. 外键关系的反向查询
  2. 多对多关联关系

常用方法

create()

创建一个新的对象,保存对象,并将它添加到关联对象集之中,返回新创建的对象。

>>> import datetime
>>> teacher_obj.cid.create(cname="9班", first_day=datetime.datetime.now())

创建一个新的班级对象,保存对象,并将它添加到关联对象集之中。返回新创建的对象:

>>> class_obj = models.Class.objects.first()
>>> class_obj.student_set.create(sname="小明")

上面的写法等价于下面的写法,但是比下面的这种写法更简单。

>>> class_obj = models.Class.objects.first()
>>> models.Student.objects.create(sname="小明", cid=class_obj)

add()

把指定的model

对象添加到关联对象集中。

添加对象

>>> class_objs = models.Class.objects.filter(id__lt=3)
>>> models.Teacher.objects.first().cid.add(*class_objs)

添加id

>>> models.Teacher.objects.first().cid.add(*[1, 2])

set()

更新model对象的关联对象。

>>> teacher_obj = models.Teacher.objects.first()
>>> teacher_obj.cid.set([2, 3])

remove()

从关联对象集中移除执行的model对象

>>> teacher_obj = models.Teacher.objects.first()
>>> teacher_obj.cid.remove(3)

对于ForeignKey对象,这个方法仅在null=True时存在。

clear()

从关联对象集中移除一切对象。

>>> teacher_obj = models.Teacher.objects.first()
>>> teacher_obj.cid.clear()

同理,对于ForeignKey对象,这个方法仅在null=True时存在。

注意:

  1. 对于所有类型的关联字段,add()、create()、remove()和clear(),set()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。

了不起的双下划线

在这之前我们所有的跨表查询都是基于对象的查询。

比如:

Django还提供了一种直观而高效的方式在查询中表示数据表之间的关联关系,它能自动确认 SQL JOIN 关系。

需要做跨关系查询时,就可以使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的 model 为止。

Python学习(三十四)—— Django之ORM之单表、联表操作的更多相关文章

  1. python学习三十四天函数高阶函数定义及用法

    python函数高阶函数是把函数当成一个变量,传递给函数作为参数,或者函数的返回值里面有函数,都称为高阶函数, 1,把函数作为参数传递 def dac(x,y): return x+y def tes ...

  2. python学习 (三十四) Python文件操作

    1 写文件 my_list = ["] my_file = open("myfile.txt", "w") for item in my_list: ...

  3. 孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习

     孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.close() 当一个file对象执行此方法时,将关闭当前 ...

  4. python 学习笔记十五 django基础

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  5. python 学习笔记十八 django深入学习三 分页,自定义标签,权限机制

    django  Pagination(分页) django 自带的分页功能非常强大,我们来看一个简单的练习示例: #导入Paginator>>> from django.core.p ...

  6. python 学习笔记十九 django深入学习四 cookie,session

    缓存 一个动态网站的基本权衡点就是,它是动态的. 每次用户请求一个页面,Web服务器将进行所有涵盖数据库查询到模版渲染到业务逻辑的请求,用来创建浏览者需要的页面.当程序访问量大时,耗时必然会更加明显, ...

  7. Python 学习第十九天 django知识

    一,django 知识总结 1,同一个name属性的标签,多个值获取 <form action="/login/" method="POST" encty ...

  8. Python 学习 第十四篇:命名元组

    Python的元组不能为元组内部的数据进行命名,而 collections.namedtuple 可以来构造一个含有字段名称的元组类,命名元组可以通过逗号+字段名来获取元素值: collections ...

  9. 笨办法学Python(三十四)

    习题 34: 访问列表的元素 列表的用处很大,但只有你能访问里边的内容时它才能发挥出作用来.你已经学会了按顺序读出列表的内容,但如果你要得到第 5 个元素该怎么办呢?你需要知道如何访问列表中的元素.访 ...

  10. python 学习笔记十六 django深入学习一 路由系统,模板,admin,数据库操作

    django 请求流程图 django 路由系统 在django中我们可以通过定义urls,让不同的url路由到不同的处理函数 from . import views urlpatterns = [ ...

随机推荐

  1. Sublime怎么安装Package control组件

    Sublime怎么安装Package control组件 藏色散人 藏色散人 2018-11-26 14:30:51 原创 Sorry, your browser does not support e ...

  2. GOOGLE RANKBRAIN 完整指南

    [译]GOOGLE RANKBRAIN 完整指南 ( 2018 最新版 ) 2018.01.29    来源  http://www.zhidaow.com/post/google-rankbrain ...

  3. jenkins在windows及linux环境下安装

    下载 下载地址: https://jenkins.io/download/ 下载windows和linux通用的war包 jenkins在windows下安装 前提:已经安装jdk.tomcat 将w ...

  4. Forget Guava: 5 Google Libraries Java Developers Should Know

    Forget Guava: 5 Google Libraries Java Developers Should Know Published on 2016 7 13 Somenath PandaFo ...

  5. Day044--javascript, ECMAScript

    一. javascript JavaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等. DOM:操作网页上的 ...

  6. 使用mysqlbinlog对主库binlog进行同步

    #!/bin/bash BASEDIR="/usr/local/mysql" BIN="$BASEDIR/bin" MYSQLBINLOG="$BIN ...

  7. openstack项目【day23】:KVM介绍

    阅读目录 什么是kvm 为何要用kvm kvm的功能 常见虚拟化模式 KVM架构 KVM工具集合 一 什么是kvm KVM 全称 Kernel-Based Virtual Machine.也就是说 K ...

  8. NOI-OJ 2.2 ID:8758 2的幂次方表示

    思路 可以把任意一个数转化为2^a+2^b+2^c+...+2^n 例如137的二进制为10001001,这就等效于2^7+2^3+2^0 以上结果如何通过程序循环处理呢?需要把数字n分解为上述公式, ...

  9. [家里蹲大学数学杂志]第057期图像复原中的改进 TV 模型

    $\bf 摘要$: 本文给出了王大凯等编的<图像处理中的偏微分方程方法>第 6.2 节的详细论述. $\bf 关键词$: 图像复原; TV 模型; matlab 编程 1. 前言 图像在形 ...

  10. Javaweb学习笔记——(二十三)——————AJAX、XStream、JSON

    AJAX概述     1.什么是AJAX         ajax(Asynchronous JavaScript and xml) 翻译成中文就是"异步JavaScript和xml&quo ...