Django 模型层 ORM 操作
运行环境
1. Django:2.1.3 version
2. PyMysql: 0.9.3 version
3. pip :19.0.3 version
4. python : 3.7 version
4. Mysql : 8.0.15 version
1. 在 配置文件 settings.py 中
注释 MIDDLEWARE 中的中间件 CSRF
2.在项目根路径下 创建静态文件夹 static , 并在 配置文件中进行配置,
在最后添加:
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"static"),
)
3.在配置文件中,配置数据库信息:
注释掉 Django 中默认数据库 Sqlite3 的配置信息。添加 MySQL如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "cnblogs_model01", # 要连接的数据库,连接前需要创建好
'USER':'root', # 连接数据库的用户名
'PASSWORD':'password', # 连接数据库的密码
'HOST':'127.0.0.1', # 连接主机,默认本级
'PORT':'' # 端口 默认3306
}
}
4.在 配置文件目录 中的 __init__.py 文件中添加:
import pymysql
pymysql.install_as_MySQLdb()
5. 若想实时 可以查看Django ORM 与数据库交互的 具体 SQL 语句,可在配置文件中 添加如下代码:
# 添加 日志记录 ,打印 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',
},
}
}
项目准备工作
from django.db import models # Create your models here.
class Author(models.Model):
aid = models.AutoField(max_length=50,primary_key=True)
name = models.CharField(max_length=100,verbose_name="姓名")
age = models.IntegerField(verbose_name="年龄") # 不加 max_length 参数
authorDetail = models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE,related_name="expand")
def __str__(self):
return self.name class AuthorDetail(models.Model):
birthday = models.DateTimeField(max_length=50,verbose_name="生日")
qq = models.BigIntegerField(verbose_name="腾讯QQ") # 不加 max_length 参数
addr = models.CharField(max_length=50,verbose_name="联系地址") def __str__(self):
return str(self.id) class Publisher(models.Model):
pid = models.AutoField(max_length=100,primary_key=True)
name = models.CharField(max_length=100)
city = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
def __str__(self):
return self.name class Book(models.Model):
bid = models.AutoField(max_length=50,primary_key=True)
title = models.CharField(max_length=100)
price = models.DecimalField(max_digits=8,decimal_places=3)
publishDate = models.DateField(max_length=50) publisher = models.ForeignKey(to="Publisher",on_delete=models.CASCADE,related_name="pu_name")
authors = models.ManyToManyField(to="Author",related_name="au_name")
def __str__(self):
return self.title
本博客ORM 操作所基于的表结构(models.py):
ORM 操作:
# 添加:
# 一对一 ,子表记录 与 主表记录 建立互为一对一的 映射,创建对象 默认可不用指定 id 字段。
# detail = AuthorDetail.objects.create(id=20,birthday="1997-08-02",qq=2145788956,addr="hunan badajie")
# obj = Author.objects.create(aid=11,name="shiwei222",age="100",authorDetail=detail)
# create() # 添加字段, 不用 save(),自动保存到 DB # 此种创建对象的方式 一定 要 save(), 才可将数据保存到数据库。相当DB中操作 Commit()
# au = AuthorDetail(id=21,birthday="1298-12-02",qq=1245785,addr="guangxi de dazita")
# au.save()
# obj = Author(aid=12,name="liping",age=45,authorDetail=au)
# obj.save()
# 更新:
# update() #对一个 QuerySet 对象集体更新
# obj = Author.objects.filter(aid__in=range(6 ,13)).update(age=1200)
# obj = Author.objects.get(aid = 10) # 获取单条数据
# obj.name = "panda"
# obj.save() # 调用属性进行赋值,要将 改变值 保存到 DB , 要sava()提交
#删除:
# dleete() # 删除 QuerySet 集合中的 所有对象
# obj = Author.objects.filter(aid__in=range(8,12)).delete()
#查询:
# obj = Author.objects.get(id=10)
# obj = Author.objects.get(aid=5) # 获取单条数据,当对象不存在 或者 当条件匹配多个对象时,都会报错。
# obj = Author.objects.all() # 获取 表中所有记录对象
# obj = Author.objects.filter(aid__in=range(1,100)) # 对表中数据进行过滤筛选
# obj = Author.objects.exclude(aid__in=range(1,100)) # 对表中数据进行反过滤, 与 filter() 相反
基本操作
#万能的双下划线
# obj = Author.objects.filter(aid__in=range(1,6)) #ID属于一个 集合,in(1,2,3,4,5) ,故不包含 6
# obj = Author.objects.filter(aid__range=[1,6]) # 范围 bettwen 100 and 200, 闭 区间, 包含 6
# obj = Author.objects.filter(aid__lt=100) # ID值 less than(小于)
# obj = Author.objects.filter(aid__lte=100)# ID less than or equal(小于等于)
# obj = Author.objects.filter(aid__gt=100)# ID greater than (大于)
# obj = Author.objects.filter(aid__gte=100) # ID greater than or equal (大于等于)
# obj = Author.objects.filter(name__contains="shi") # 包含指定 字符的
# obj = Author.objects.filter(name__icontains="wang") # 包含指定 字符的, 但不区分大小写
# obj = Author.objects.filter(name__endswith="s") # 以指定字符结尾的,
# obj = Author.objects.filter(name__iendswith="s") # 以指定字符结尾的,但不区分大小写
# obj = Author.objects.filter(name__startswith="wan") # 以指定字符开头的,
# obj = Author.objects.filter(name__istartswith="mei") # 以指定字符开头的, 但不区分大小写
# obj = Author.objects.filter(name__regex=r' *.a') # 正则表达式匹配,
# obj = Author.objects.filter(name__iregex=r' *.li') # 正则表达式匹配,不区分大小写 # filter(**kwargs) 方法 条件 与 操作
# obj = Author.objects.filter(aid__gte=10,aid__lte=50)
# obj = Author.objects.filter(aid__in=range(10,100),name__contains="shi") # obj = Author.objects.filter(aid__in=range(1,100)).order_by("aid") # 对 QuerySet集合元素根据 aid 字段 asc
# obj = Author.objects.filter(aid__in=range(1,100)).order_by("-aid") # 对 QuerySet集合元素根据 aid 字段 desc
#
# obj = Author.objects.filter(aid__in=range(1,100)).count() # 查询 QuerySet集合的 长度
# obj = Author.objects.filter(aid__in=range(1,100)).first() # 查询 QuerySet集合 中的第一个 元素
# obj = Author.objects.filter(aid__in=range(1,100)).last() # 查询 QuerySet集合 中的最后一个元素 # obj = Book.objects.filter(publishDate__year__range=[2000,2555]) # BETWEEN 2000 AND 2555 ,包含2555
# obj = Book.objects.filter(publishDate__year__in=range(2000,2555))# IN(2000, ....,2553,2554)
# obj = Book.objects.filter(publishDate__month__gt=6) # > 6
# obj = Book.objects.filter(publishDate__day__lt=6) # < 6
# obj = Book.objects.filter(publishDate__week_day=4) # 映射 星期几,星期日:1 ,星期六:7
# # 注意区分与 datetime.date(2017,2,23).weekday() # 映射 星期几,0 表示 星期 一
# # 注意区分与 datetime.date(2017,2,23).isoweekday() # 映射 星期几,1 表示 星期 一
# obj = AuthorDetail.objects.filter(birthday__hour=12)
# obj = AuthorDetail.objects.filter(birthday__minute__lt=12)
# obj = AuthorDetail.objects.filter(birthday__second__gt=30)
# obj = AuthorDetail.objects.filter(birthday__hour__range=[8,20]) # 闭区间
进阶操作
# 高级操作:
#F and Q :
from django.db.models import F,Q
# obj = Author.objects.filter(aid=6).update(age = F('age')+100)
# 默认情况下,filter(),exclude(),get(), 方法中的条件以逗号分隔, 都为 与 运算, and 操作,
# 要想实现 或运算,也就是 or 操作, 则用 Q 查询:
# obj = Author.objects.filter(Q(aid=4)|Q(age=80)) # or 运算
# obj = Author.objects.filter(Q(aid=4)&Q(age=80)) # and 运算
# obj = Author.objects.filter(Q(age=80)).count() #
# 小飘的使用:
# 下方 的 两条查询语句所执行的 SQL 语句一模一样, 故 one = two,
# one = Author.objects.filter(~Q(age=80)).count() # WHERE NOT
# two = Author.objects.exclude(Q(age=80)).count() # WHERE NOT # 注意: 当关键字参数 和 Q对象 组合使用时, Q对象必须放在前面。否则报错。
# obj = Author.objects.filter(Q(aid__gt=15)|Q(aid__lte=1)&Q(name='shiweiIslion'),aid__gt=10)
# SQL语句为: where (( aid > 15 or ( aid <=1 and name = 'shiwei' )) and aid > 10 )
# obj = Author.objects.filter(Q(aid__gt=15)|Q(aid__lte=1)&~Q(name='shiweiIslion'),aid__gt=10)
# SQL语句为: where (( aid > 15 or ( aid <=1 and not ( name = 'shiwei' ))) and aid > 10) # 执行 原生 SQL 语句: 依赖 与 Django 正常运行的情况下 :
# from django.db import connection,connections
# cursor = connection.cursor() # cursor = connections['default'].cursor()
# cursor.execute("""SELECT * FROM shiwei_author where aid = %s""",(1,))
# obj = row = cursor.fetchone()
# QuerySet 切片操作: 下标 从 0 开始
# obj = Author.objects.all()[1:4] # LIMIT 3 左闭右开 区间
# 左闭右开 区间,每 两 个为一组,只显示每组 第一个
# obj = Author.objects.all()[1:7:2] # 实际 SQL 语句为 LIMIT 6 OFFSET 1
# 左闭右开 区间,每 三 个为一组,只显示每组 第一个
# obj = Author.objects.all()[1:7:3] # 实际 SQL 语句为 LIMIT 6 OFFSET 1 from django.db.models import Count,Max,Min,Sum,Avg
# group by 操作:annotate(**kwargs) : 提供聚合表达式查询方法,
# values('aid','age').annotate(**kwargs) # 结果为列表对象, 元素为 字典对象
# values_list('aid','age').annotate(**kwargs) # 结果为列表对象, 元素为 元祖 对象
# 可写多个参数,每个参数都是一个annotation,它将添加到返回结果对象中。就是原生SQL 的 select 返回字段中。
# 每个参数 可指定别名, 匿名参数将基于 字段名__聚合函数名称 来自动生成 : 例如:
# annotate(Count('name')) # select Count('name') AS name__count,........
# annotate(shi=Count('name')) # select Count('name') AS shi,........
# annotate(shi=Count('name'),wei=Sum('age')) # select Count('name') AS shi,Sum('name') AS wei,.......
# values() 和 values_list() 方法中参数若 存在主键字段, 则自动以 主键 分组,相当于没有分组。
# 在没有 主键字段的情况下, 有一个字段,就按此字段分组, 有多个字段, 则以这几个字段为联合字段进行分组。 # 以 ('aid')字段 为分组依据,
# obj = Author.objects.filter(aid__gt=15).annotate(shi = Count('age')).values('aid','name','shi')
# 结果为:<QuerySet [{'aid': 16, 'name': 'shiweiIslion', 'shi': 1}, {'aid': 17, 'name': '李克强', 'shi': 1}]> # 以 ('name') 字段 为分组依据, 统计每组的年龄最大者为一个新的字段, 字段名为 wei
# obj = Author.objects.filter(aid__gt=1).values('name').annotate(wei=Max("age"))
# 结果为:<QuerySet [{'name': '王安石·', 'wei': 78}, {'name': '忽而覆盖', 'wei': 80}]> # 以 ('name') 字段为分组依据,再根据一对一键 ,统计每组的关联字段的生日的 最小者。
# obj = Author.objects.filter(aid__gt=10).values('name').annotate(wan=Min("authorDetail__birthday"))
# 结果为:<QuerySet [{'name': 'liping', 'wan': datetime.datetime(1298, 12, 2, 0, 0, tzinfo=<UTC>)}, {'name': 'lihaimei', 'wan': datetime.datetime(1205, 5, 6, 0, 0, tzinfo=<UTC>)}]> # 对 values() 方法 的参数为分组依据, 统计每组的 年龄总和,为一个新的字段, 字段名叫 shi
# obj = Author.objects.all().values_list('name').annotate(shi=Sum('age'))
# 结果为:<QuerySet [('莫言', 56), ('王安石·', 78), ('忽而覆盖', 80), ('但丁', 3918)]> # 对 values() 的 参数 'name' 进行分组,并且统计每组的行数,得到一个新的字段, 字段名 为 shi
# obj = Author.objects.filter(aid__gt=1).values('name').annotate(shi=Count('age'))
# 结果为: <QuerySet [{'name': '王安石·', 'shi': 1}, {'name': '忽而覆盖', 'shi': 1}]> # QuerySet 对象
# QuerySet 转化为 List 对象
# list(obj) 等于: [{'name': '王安石·', 'shi': 1}, {'name': '忽而覆盖', 'shi': 1}]
# 以('age','name','authorDetail') 为分组依据
# obj = Author.objects.filter(aid__gt=10).values_list('age','name','authorDetail').annotate(shi=Count('age'),wei=Sum('age'))
# 以 ('aid') 为分组依据。
# obj = Author.objects.filter(aid__gt=10).values('age','name','authorDetail','aid').annotate(Count('name'),wei=Sum('age')) # obj = Author.objects.filter(aid__lt=100).values_list('name', 'age').annotate(shi=Sum('age')).values_list('name')
# 结果为: <QuerySet [('莫言',), ('王安石·',), ('忽而覆盖',), ('但丁',)]> # 最后一个 有 ("aid") 字段, 则 聚合函数 以 ("aid") 字段分组
# obj = Author.objects.filter(aid__lt=100).values_list('name', 'age').annotate(shi=Sum('age')).values_list('name','aid')
# 结果为: <QuerySet [('莫言', 1), ('王安石·', 2), ('忽而覆盖', 3), ('但丁', 4)]> # 以 ('name','age','authorDetail__qq') 为分组依据。
# obj = Author.objects.filter(aid__lt=100).values_list('name', 'age').annotate(shi=Sum('age')).values_list('name','authorDetail__qq')
# 结果为: <QuerySet [('莫言', 54545), ('王安石·', 145122152), ('忽而覆盖', 2464124454125)]> # 按照最后一个 values_list() # 以 ('name','age','authorDetail__qq') 为分组依据。
# obj = Author.objects.filter(aid__lt=100).values_list('name', 'age').annotate(shi=Sum('age')).values('name','authorDetail__qq')
# 结果为: <QuerySet [{'name': '莫言', 'authorDetail__qq': 54545}, {'name': '王安石·', 'authorDetail__qq': 145122152}]> # 对分组查询结果 进一步进行 筛选
# obj = Author.objects.values_list("age","name").annotate(shi=Count("name",distinct=True)).filter(aid__gt=15) # order_by 操作:
# obj = Author.objects.order_by('name','age')
# obj = Author.objects.order_by('age','name') # 先按照 年龄 asc 排序,再按照 name asc 排序。 # reverse() : 第二次调用reverse()将恢复到原有的排序
# obj = Author.objects.order_by('name','age').reverse()[:3] # 获取前三个元素, 不支持负索引
Django 模型层 ORM 操作的更多相关文章
- Django模型层—ORM
目录 一.模型层(models) 1-1. 常用的字段类型 1-2. 字段参数 1-3. 自定义char字段 1-4. 外键关系 二.Django中测试脚本的使用 三.单表操作 3-1. 添加记录 3 ...
- Django模型层ORM学习笔记
一. 铺垫 1. 连接Django自带数据库sqlite3 之前提到过Django自带一个叫做sqlite3的小型数据库,当我们做本地测试时,可以直接在sqlite3上测试.不过该数据库是小型的,在有 ...
- 模型层ORM操作
一.ORM操作 1.关键性字段及参数 DateField 年月日 DateTimeField 年月日时分秒 auto_now: 每次操作改数据都会自动更新时间 auto_now_add: 新增数据的时 ...
- python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)
昨日内容回顾 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 Quer ...
- {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询
Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...
- Django基础(2)--模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介
没整理完 昨日回顾: 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 ...
- Django模型层之ORM
Django模型层之ORM操作 一 ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软 ...
- Django模型层之单表操作
Django模型层之单表操作 一 .ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软 ...
- Django模型层之更多操作
Django模型层之更多操作 一 .ORM字段 1.1 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为 ...
随机推荐
- 洛谷P4331[BOI2004] sequence
博客复活? 这个题很模板啊.随便上个左偏树.之前第一遍写对了.然后今天翻出来又写了一遍发现了一个奇奇怪怪的问题. 对比如下 上面的是AC 下面的WA 真的是一个很蠢的问题...你TM堆顶都弹出来了,堆 ...
- C#-弄懂泛型和协变、逆变
脑图概览 泛型声明和使用 协变和逆变 <C#权威指南>上在委托篇中这样定义: 协变:委托方法的返回值类型直接或者间接地继承自委托前面的返回值类型; 逆变:委托签名中的参数类型继承自委托方法 ...
- Linux 多个cpp文件的编译(Makefile)
打包so文件: CC = g++ CFLAGS=-Wall -O2 -fPIC TARGET = libbg.so SRCS := $(wildcard *.cpp) OBJS := $(patsub ...
- Kafka长文总结
Kafka是目前使用较多的消息队列,以高吞吐量得到广泛使用 特点: 1.同时为发布和订阅提供搞吞吐量.Kafka的设计目标是以时间复杂度为O(1)的方式提供消息持久化能力的,即使对TB级别以上数据也能 ...
- 线程join方法demo-模拟叫号看病
package cn.chapter4.test5; public class SicknessDemo { /** * 模拟叫号看病 * @param args * * 思路:把普通号看病写在主线程 ...
- 牛客假日团队赛9 A 乘积最大 (简单DP)
题目:https://ac.nowcoder.com/acm/contest/1071/A 题意:给你一个串,然后给你m个乘号,用m个乘号分割开这个串,然后求分割可以求出的最大值 思路:首先范围很小 ...
- ibatis 的使用
1. 文本的使用 select ‘day’+Num from Table;//Sql select convert(varchar,'day')+Num from Table;//ibatis
- HDU 3183 A Magic Lamp(RMQ问题, ST算法)
原题目 A Magic Lamp Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- Python 进阶_OOP 面向对象编程_类属性和方法
目录 目录 类属性 调用类属性 查看类属性 特殊的类属性 类方法 真构造器 __new__ 类属性 在理解类属性之前要先搞清楚 实例属性 和 函数属性 之间的区别: 1. 实例属性:指的是实例化类对象 ...
- 用 Flask 来写个轻博客 (21) — 结合 reCAPTCHA 验证码实现用户注册与登录
目录 目录 前文列表 扩展阅读 添加账户管理蓝图 新建控制器蓝图 新建表单 新建蓝图 main 的视图函数 新建模板 页面效果 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Fla ...