(day53)五、模型层(ORM)、settings文件配置
一、settings配置
(一)测试文件配置
django中的tests.py测试文件需要配置后,才可以运行测试脚本,可以直接在tests.py文件中,也可新建任意.py文件
- manege.py文件中拷贝代码:
- 导入django,并作配置
- 导入想要测试应用的文件
- 编写测试代码
# tests.py
# 1. 从manage.py中拷贝以下代码
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
# 2.导入django,并作配置
import django
django.setup()
# 3. 导入想要测试应用的文件
from app01 import models
# 4. 编写测试代码
(二)查看对应sql语句
- 直接在配置文件中配置相应代码就可以查看所有的orm语句所对应的sql语句, 配置好之后,再执行任何对数据库进行操作的语句时,会自动将Django执行的sql语句打印到pycharm终端上
- 除了配置外,还可以通过一点.query即可查看查询语句
# settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
二、模型表数据的增删改查
(一)创建数据
(1)create方法
book_obj = models.Books.objects.create(title='三国演义',price=123.23,publish_date='2019-11-11')
(2)利用对象的绑定方法
book_obj = models.Books(title = '西游记',price =666,publish_date = '2002-01-11')
book_obj.save()
(二)修改数据
(1)利用queryset方法
pk会自动查找到当前表的主键字段
models.Books.objects.filter(pk=1).update(price=444.66) # pk指代主键字段
(2)利用对象
该方法其实是内部所有数值都修改一遍,不推荐使用
book_obj = models.Books.objects.get(pk=1)
book_obj.save()
(三)删除数据
(1)利用queryset方法
models.Books.objects.filter(pk=3).delete()
(2)利用对象
book_obj = models.Books.objects.get(pj=3)
book_obj.delete()
(四)查询数据
(1)查询方法13条
orm语句默认惰性查询:只有在使用的时候才会执行,不使用就不会执行
all():查询所有的数据对象,返回queryset对象(类列表对象)
res = models.Books.objects.all()
filter():筛选出对应的数据对象,返回queryset对象,如果不存在返回空(相当于where)
res = models.Books.objects.filter(pk=1,title = '三国演义') # 支持多个参数,and关系
get():筛选出对应数据对象,返回数据对象,如果不存在直接报错
res = models.Books.objects.get(pk=1)
first() :返回queryset中第一个数据对象
res = models.Books.objects.filter(title = '西游记').first()
last() :返回queryset中最后一个数据对象
res = models.Books.objects.filter(title='西游记').last()
count():统计数据的个数
num = models.Books.objects.count()
values():获取数据对象中指定的字段值,可以有多个,返回queryset对象(列表套字典)
res = models.Books.objects.values('title','price')
values_list():获取数据对象中指定的字段值,可以有多个,返回queryset对象(列表套元组)
res = models.Books.objects.values_list('title','price')
order_by():数据对象按照指定的字段排序
# 升序 res = models.Books.objects.order_by('price') res = models.Books.objects.all().order_by('price') # 等价,语义更明确 # 降序:字典前面加负号 res = models.Books.objects.all().order_by('-price')
reverse():反转,对象必须有顺序(要提前排序之后才能使用)
# 错误用法 res = models.Books.objects.all() res1 = models.Books.objects.all().reverse() # 正确用法 res = models.Books.objects.all().order_by('price') res1 = models.Books.objects.all().order_by('price').reverse()
exclude():排除···之外
res = models.Books.objects.all().exclude(title='三国演义')
exists():判断查询结果是否有值,返回布尔值
res = models.Books.objects.filter(pk=1).exists() # 和filter方法作用重复
distinct():对查询结果去重,数据必须是完全相同的的情况下(主键永远不会相同)
# 一般与values联用 res = models.Books.objects.values('title','price').distinct()
(2)双下划线查询
__gt:大于
# 查询价格大于500的书籍 res = models.Books.objects.filter(price__gt=500) print(res)
__lt:小于
# 查询价格小于400 的书籍 res = models.Books.objects.filter(price__lt=400) print(res)
__gte:大于等于
# 查询价格大于等于500 res1 = models.Books.objects.filter(price__gte=444.66) # 对数字精确度不敏感 res = models.Books.objects.filter(price__gte=500) print(res)
__lte:小于等于
# 查询价格小于等于500的书籍 res = models.Books.objects.filter(price__lte=500) print(res)
__in:
# 查询价格是222或者444或者500的书籍 res = models.Books.objects.filter(price__in=[222,444,500]) print(res)
__range:范围,顾头顾尾
# 查询价格在200到800之间的书籍 res = models.Books.objects.filter(price__range=(200,800)) # 顾头顾尾 print(res)
_date:获取年月日,后面可以加参数获取date的特点部分数据
- __year:获取年
- __month:获取月份
- __day:获取日
- __week_day:获取工作日
# 查询出版日期是2019年的书籍 res = models.Books.objects.filter(publish_date__year='2019') print(res) # 查询出版日期是1月份的书籍 res = models.Books.objects.filter(publish_date__month='1') print(res)
__startswith:以···开头
# 查询书籍是以三开头的书 res = models.Books.objects.filter(title__startswith='三') print(res)
__endswith:以···结尾
# 查询书籍是以义结尾的书 res = models.Books.objects.filter(title__endswith='1') print(res)
__contains:包含,区分大小写
# 查询书籍名称中包含游字的书籍 res = models.Books.objects.filter(title__contains='游') print(res)
__icontains:包含,忽略大小写
# 查询书籍名称中包含字母p的书籍 res = models.Books.objects.filter(title__icontains='p') # 忽略大小写 加i print(res)
三、外键关系的增删改
(一)增
(1)一对多create
根据实际字段
models.Book.objects.create(title='三国演义',price=222.33,publish_id=1)
根据数据对象
publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.create(title='红楼梦',price=111.33,publish=publish_obj)
(2)多对多add
向第三张关系表添加数据,支持数字和对象,支持传多个
根据实际字段
book_obj= models.Book.objects.filter(pk=2).first() # book_obj.authors # 代表第三张表 book_obj.authors.add(1) # 在第三张表里面给书籍绑定一个主键为1的作者 book_obj.authors.add(1,2) # 在第三张表里面给书籍绑定一个主键为1和2的作者
根据数据对象
book_obj= models.Book.objects.filter(pk=2).first() author_obj1 = models.Author.objects.filter(pk=1).first() author_obj2 = models.Author.objects.filter(pk=2).first() book_obj.authors.add(author_obj1) book_obj.authors.add(author_obj1,author_obj2)
(二)删
(1)一对多delete
级联删除,级联更新
models.Publish.objects.filter(pk=1).delete() # 删除后对应外键表的字段中数据也会删除
(2)多对多(remove、clear)
remove:删除,可以传数字和对象,支持传多个
# 根据主键字段名删除第三张表中另一个表的数据对象 book_obj= models.Book.objects.filter(pk=2).first() book_obj.authors.remove(1) # 根据数据对象 author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() book_obj.authors.remove((author_obj,author_obj1))
clear:清空某个数据在第三张表的所有记录
book_obj= models.Book.objects.filter(pk=2).first() book_obj.authors.clear()
(三)改
(1)一对多update
根据字段改
models.Book.objects.filter(pk=4).update(publish_id=2)
根据字段对象改
publish_obj = models.Publish.objects.filter(pk=1).first() models.Book.objects.filter(pk=4).update(publish = publish_obj)
(2)多对多set
set修改多对多关系表中的数据,既可以传数字,也可传对象,但是括号内必须是可迭代对象,都支持多个
根据字段改
book_obj= models.Book.objects.filter(pk=2).first() book_obj.authors.set((1,3))
根据字段对象改
author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() book_obj.authors.set((author_obj,author_obj1))
四、多表查询
(一)正反向查询
正向查询按字段,反向查询按表名小写_set
- 正向查询:从关系字段所在的表查询另一个表
- 反向查询:从关系字段不在的表查询另一张表
(二)基于对象查询
相当于子查询
(1)正向查询
- 先拿到对象,在通过对象去查相应的外键字段
- 当正向查询点击外键字段数据有多个的情况下,需要用all
# 1. 查询书籍主键为2的出版社名称
book_obj = models.Book.objects.filter(pk=2).first()
print(book_obj.publish.name)
# 2. 查询书籍主键为4的作者姓名
book_obj = models.Book.objects.filter(pk=4).first()
print(book_obj.authors) # app01.Author.None
print(book_obj.authors.all()) # <QuerySet [<Author: Author object>, <Author: Author object>]>
# 3. 查询作者是json的手机号码
author_obj= models.Author.objects.filter(name='json').first()
print(author_obj.author_detail.phone)
(2)反向查询
- 一对多和多对多的时候加_set (查询结果有多种)
- 一对一的时候不需要加_set(查询结果只有一种)
# 4. 查询出版社是东方出版社出版过的书籍
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
print(publish_obj.book_set.all())
# 5. 查询作者是json写过的书籍
author_obj = models.Author.objects.filter(name='json').first()
print(author_obj.book_set.all())
# 6. 查询手机号是120的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
print(author_detail_obj.author.name)
(三)基于双下划线查询
相当于多表联查,__
相当于join的作用,查询时如果字段名是关联的另一张表的就使用双下划线
(1)正向查询
# 1. 查询书籍pk为2的出版社名称
res =models.Book.objects.filter(pk=2).values('publish__name') # 表示拼接关联后的表
print(res)
# 4. 查询出版社是东方出版社出版过的书的名字
res = models.Book.objects.filter(publish__name='东方出版社').values('title')
print(res)
# 5. 查询书籍pk为2的作者的手机号
res = models.Book.objects.filter(pk=2).values('authors__author_detail__phone')
print(res)
(2)反向查询
# 1. 查询书籍pk为2的出版社名称
res = models.Publish.objects.filter(book__pk=2).values('name')
print(res)
# 4. 查询出版社是东方出版社出版过的书的名字
res = models.Publish.objects.filter(name='东方出版社').values('book__title')
print(res)
# 5. 查询书籍pk为2的作者的手机号
res = models.Author.objects.filter(book__pk=2).values('author_detail__phone')
print(res)
五、常用字段和参数
(一)常用字段
(1)AutoField
int自增列,必须填入 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
# 对应关系:
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)',
(2)IntegerField
整数类型,范围在 -2147483648 to 2147483647
(3)CharField
- 字符类型,必须提供max_length参数, max_length表示字符长度
- Django中的CharField对应的MySQL数据库中的varchar类型,没有设置对应char类型的字段 ,但是可以自定义(详见附录)
(4)DateField
日期字段,日期格式YYYY-MM-DD`,相当于Python中的datetime.date()实例
(5)DateTimeField
日期时间字段,格式YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
,相当于Python中的datetime.datetime()实例。
(二)字段参数
(1)DateField和DateTimeField
- auto_now_add:创建数据记录的时候会把当前时间添加到数据库,
auto_now_add=True
- auto_now:每次更新数据记录的时候会更新该字段 ,
auto_now=True
(2)通用参数
- null:用于表示某个字段可以为空
- unique:如果设置为unique=True 则该字段在此表中必须是唯一的
- db_index:如果db_index=True 则代表着为此字段设置索引
- default:为该字段设置默认值
(day53)五、模型层(ORM)、settings文件配置的更多相关文章
- python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)
昨日内容回顾 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 Quer ...
- Django基础(2)--模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介
没整理完 昨日回顾: 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 ...
- Django模型层—ORM
目录 一.模型层(models) 1-1. 常用的字段类型 1-2. 字段参数 1-3. 自定义char字段 1-4. 外键关系 二.Django中测试脚本的使用 三.单表操作 3-1. 添加记录 3 ...
- 1127 模型层orm表操作
目录 昨日回顾 模型层 1.配置测试脚本 1.1 应用下tests文件 1.2 新建任意名称文件 2. 数据的增删改查 2.1 创建数据 2.2 修改数据 2.3 删除数据 2.4查询数据 十三门徒 ...
- Django模型层ORM学习笔记
一. 铺垫 1. 连接Django自带数据库sqlite3 之前提到过Django自带一个叫做sqlite3的小型数据库,当我们做本地测试时,可以直接在sqlite3上测试.不过该数据库是小型的,在有 ...
- 模型层ORM操作
一.ORM操作 1.关键性字段及参数 DateField 年月日 DateTimeField 年月日时分秒 auto_now: 每次操作改数据都会自动更新时间 auto_now_add: 新增数据的时 ...
- 07 模型层 orm相关查询 F查询Q查询 django开启事务
一.Django终端打印SQL语句 如果你想知道你对数据库进行操作时,Django内部到底是怎么执行它的sql语句时可以加下面的配置来查看 在Django项目的settings.py文件中,在最后复制 ...
- Django 模型层 ORM 操作
运行环境 1. Django:2.1.3 version 2. PyMysql: 0.9.3 version 3. pip :19.0.3 version 4. python : 3.7 versio ...
- 07 -模型层ORM
1.orm简介 2. models.py from django.db import models # Create your models here. class Book(models.Model ...
随机推荐
- Linux 的 Crond(二)
最近由于工作中用到了crond,之前对crond不是很了解,只知道咋用,但是这次需要考虑好多情况,所以又深入了解了一下crond,下面就以下几个问题来谈谈crond. crond 中指定的job,如果 ...
- Codeforces Round #599 (Div. 1) A. Tile Painting 数论
C. Tile Painting Ujan has been lazy lately, but now has decided to bring his yard to good shape. Fir ...
- navicat连接mysql报错1251解决方案,从头搭建node + mysql 8.0 (本人亲测有效)
准备学node 好久了 一直没有动手去写,今天突发奇想,然后就安装了一个mysql (找了一个博客跟着步骤去安装的),然后打算用node 写个增删改查. 1.下载mysql安装包 地址: http ...
- python TKinter的主窗口运行程序完毕后,怎么让其自动关闭
如题: 在pycharm 调试Tkinter程序的时候,关闭右上角的X 实际上并未退出进程,长期以往 再大的内存也会被耗尽. 一般就是下面的代码: """ from tk ...
- Python远程linux执行命令
1.远程登录到linux上,使用到的模块paramiko #远程登陆操作系统 def ssh(sys_ip,username,password,cmds): try #创建ssh客户端 client ...
- Python - 部分PEP8规范
写代码就像写字一样,为什么有的人写的字十分漂亮,而有的人写的字过后连自己都不认识,最主要还是从一开始是否对自己严格要求.从现在开始就当自己是个初学者,把代码写漂亮点.以下截取了部分PEP8代码规范,里 ...
- java高并发系列 - 第8天:线程组
线程组 我们可以把线程归属到某个线程组中,线程组可以包含多个线程以及线程组,线程和线程组组成了父子关系,是个树形结构,如下图: 使用线程组可以方便管理线程,线程组提供了一些方法方便方便我们管理线程. ...
- 3DES对称加密算法(ABAP 语言实现版)
公司人事数据要求在系统间加密传输,而对接系统大部分是Java系统,要在不同的异构系统间能很好的加解密码,想到了标准的对称加密算法DES,因为是标准的算法,网络上存在大量公开用Java的DES算法,JA ...
- ABAP 新语法记录(一)
原文链接:https://www.cnblogs.com/learnning/p/10647174.html 主要内容 内联声明 构造表达式 内表操作 Open SQL 其他 本文列出了ABAP新语法 ...
- Java日期时间API系列2-----Jdk7及以前的日期时间类在mysql数据库中的应用
1.java中与数据库相关的时间类 java提供与mysql方便交互的三种数据类型: java.sql.Date java.sql.Time java.sql.Timestamp 它们都是继承java ...