(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 ...
随机推荐
- JVM-2-JVM结构
什么是JVM JVM是可运行Java代码的假想计算机 (或者理解为一种规范),包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回收,堆 和 一个存储方法域.JVM是运行在操作系统之上的 ...
- 大数据量数据库设计与优化方案(SQL优化)
转自:http://blog.sina.com.cn/s/blog_6c0541d50102wxen.html 一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的 ...
- AcWing 37. 树的子结构
题目描述 地址https://www.acwing.com/problem/content/35/输入两棵二叉树A,B,判断B是不是A的子结构. 我们规定空树不是任何树的子结构. 样例 树A: / ...
- Python 列表生成式 & 字典生成式
Python 列表生成式 & 字典生成式 通过生成式可以更加简洁地生成列表和字典 列表生成式 对比 直接生成数据后加入列表示例: user_list = list() for i in ran ...
- ASP.NET Core 中基于 API Key 对私有 Web API 进行保护
这两天遇到一个应用场景,需要对内网调用的部分 web api 进行安全保护,只允许请求头账户包含指定 key 的客户端进行调用.在网上找到一篇英文博文 ASP.NET Core - Protect y ...
- node 下载 md5.js
命令:npm install js-md5
- 害死人不偿命的(3n+1)猜想-PTA
卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 (3n+1) 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 ...
- Java开发桌面程序学习(12)——Javafx 悬浮窗提示 tooptip
Javafx 悬浮窗提示 tooptip 鼠标悬浮在某个控件,弹出提示,效果如下: 代码: //control是某个控件 Tooltip.install(control, new Tooltip(&q ...
- .NET MVC5简介(五)管道处理模型IHttpModule
https://www.cnblogs.com/JimmyZhang/archive/2007/09/04/880967.html IHttpModule HTTPRuntime(运行时).在一个控制 ...
- 数据库系统原理(第四章:SQL与关系数据库基本操作 )
一.SQL概述 sql是结构化查询语言(Structured Query Language,SQL)是专门用来与数 据库通信的语言,它可以帮助用户操作关系数据库. SQL的特点: SQL不是某个特定数 ...