Django单表操作
一.Django 测试环境搭建
当你只是想测试django中的某一个py文件内容 那么你可以不用书写前后端交互的形式, 而是直接写一个测试脚本即可:
1.方式一
- 使用脚本形式:任意创建一个 py 文件, 在该文件内书写固定的配置(可以去manage.py文件中去复制前四行)
# 测试环境的准备 去manage.py中拷贝前四行代码 然后自己写两行
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Student_System.settings")
import django
django.setup()
# 在这个代码块的下面就可以测试django里面的单个py文件了(注意: 导模块也要写在这下面)
2.方式二
- 直接使用pycharm提供的Python console窗口
补充:
- 使用
pycharm
链接数据库都需要提前下载对应的驱动 - 自带的
sqlite3
对日期格式数据不敏感,如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3
二、单表查询关键字操作之增删改
1.准备表
# 在models.py文件准备表
class Books(models.Model):
title = models.CharField(verbose_name='书名', max_length=32)
price = models.DecimalField(verbose_name='价格', max_digits=8, decimal_places=2)
publish_time = models.DateField(auto_now_add=True)
'''
auto_now:每次修改数据的时候都会自动更新当前时间
auto_now_add:只在数据创建的时候记录一次创建时间,后续不会自动更改
'''
# 然后使用数据库迁移同步命令
python3 manage.py makemigrations
manage.py migrate
2.增
#方式一:create方法
res = models.Books.objects.create(title='十年', price=9.9)
#方式二:创建对象再()save保存
ccd = models.Books(title='庆余年',price=18.1)
ccd.save()
3.删
bool_obj = models.Books.objects.filter(title='十年', price=9.9).delete()方式一:delete方法
row = models.Books.objects.all().delete()
print(row) # row 为影响的条数
rows = models.Books.objects.filter(pk=2).delete() #删除主键字段为2的
方式二:获取对象再进行删除delete()
bool_obj = models.Books.objects.filter(title='十年', price=9.9).delete()
4.改
方式一:update()
models.Books.objects.filter(title='创业邦').update(price=99)
方式二:get()获取对象再进行赋值再save()保存
book_obj = models.Books.objects.get(pk=9)
book_obj.price = 999.99
book_obj.save() # 效率低(所有字段重新写一遍)
补充:
1.pk能够自动查找到当前表的主键字段 我们不需要查看当前表主键字段名
2.get括号内可以放多个参数 默认是and关系 不推荐使用 条件不符合直接报错
三、QuerySet对象查询方法介绍与单表查询
1.QuerySet介绍
-
数据库接口相关的接口(QuerySet API)
-
QuerySet对象它是一个生成器,也可以将其看成一个列表
-
ORM提供了13种查询API
2.ORM13种查询API介绍
1.all():查询所有结果
- 返回QuerySet对象
- 用
.all( )
取值的时候,不会一下子全部取出来, 而是每次只取21条 (LIMIT21)
res = models.Books.objects.all()
print(res) # <QuerySet [<Books: Books object (9)>, <Books: Books object (10)>, <Books: Books object (12)>, <Books: Books object (13)>, <Books: Books object (15)>, <Books: Books object (16)>, <Books: Books object (18)>, <Books: Books object (19)>]>
2.filter(**kwargs):过滤
- 返回QuerySet对象. 筛选出与所给筛选条件相匹配的数据对象
- 不指定筛选条件则默认查询所有
- 当结果不存在返回空的QuerySet对象, 布尔值为False
res = models.Books.objects.filter(title='创业邦')
print(res) #<QuerySet [<Books: Books object (9)>, <Books: Books object (12)>, <Books: Books object (15)>, <Books: Books object (18)>]>
bok_obj = models.Books.objects.filter() # 筛选所有,等同于帅选所有
print(bok_obj) #<QuerySet [<Books: Books object (9)>, <Books: Books object (10)>, <Books: Books object (12)>, <Books: Books object (13)>, <Books: Books object (15)>, <Books: Books object (16)>, <Books: Books object (18)>, <Books: Books object (19)>]>
book_obj = models.Books.objects.filter(pk=8888)
print(book_obj, bool(book_obj)) #<QuerySet []> False
3.get( **kwargs ) : 筛选表中的数据对象
- 直接获取数据对象
- 只能指定一个筛选条件,如果指定的筛选条件返回的结果不唯一 或者不存在抛出异常
book_get_queryset = models.Books.objects.get(pk=10)
print(book_get_queryset) # Books object (10)
条件不存在抛出异常
book_obj = models.Books.objects.get(pk=8888) #app01.models.DoesNotExist: Books matching query does not exist.
book_get_queryset = models.Books.objects.get(title='十年') #get() returned more than one Books -- it returned 3!
4.last():最后一个对象
- 获取QuerySet列表中最后一个数据对象.
- 如果QuerySet对象为空, 再使用它返回None
book_last_queryset = models.Books.objects.filter().last()
print(book_last_queryset) #Books object (22)
book_last_queryset = models.Books.objects.filter(pk=999).last()
print(book_last_queryset) # None
5.first( ) : 第一个对象
- 直接获取QuerySet列表中第一个数据对象.
- 如果QuerySet对象为空, 再使用它返回None
book_first_last = models.Books.objects.filter(title='庆余年').first()
print(book_first_last) #Books object (10)
book_first_queryset = models.Books.objects.filter(pk=8888).first()
print(book_first_queryset) #None
6.values(*field) :返回指定字段对象集
- 返回QuerySet对象,内部是一种列表套字典的格式
- 字典的key就是指定的字段名,指定字段若不存在抛出异常
book_values_queryset=models.Books.objects.values('title','price')
print(book_values_queryset) #<QuerySet [{'title': '创业邦', 'price': Decimal('999.99')},,... {'title': '十年', 'price': Decimal('9.90')}]>
#注意:指定字段不存在抛出异常
book_values_queryset = models.Books.objects.values('xxxx')
print(book_values_queryset) #django.core.exceptions.FieldError: Cannot resolve keyword 'xxxx' into field. Choices are: id, price, publish_time, title
7.values_list(*field):返回指定字段对象集
- 返回QuerySet对象, 内部是一种列表套元组的格式
- 字典的key就是指定的字段名,指定字段不存在就抛出异常
book_values_queryset = models.Books.objects.values_list('title', 'price')
print(book_values_queryset) #<QuerySet [('创业邦', Decimal('999.99')), ... ('十年', Decimal('9.90'))]>
#指定字段不存在就抛出异常
book_values_queryset = models.Books.objects.values_list('xxx')
print(book_values_queryset) #django.core.exceptions.FieldError: Cannot resolve keyword 'xxx' into field. Choices are: id, price, publish_time, title
8.distinct():去重
- 注意: 必须排除主键字段 或 唯一字段才会有意义
- 要排除使用filter无法晒选,一般用在
.values()
或.value_list()
后面
book_values_queryset = models.Books.objects.values_list('title')
dis_book_queryset = book_values_queryset.distinct()
print(dis_book_queryset) #<QuerySet [('创业邦',), ('庆余年',), ('十年',)]>
9.order_by(*field):排序
- 对查询结果进行指定字段的排序
- 默认升序. 如果想要降序在对应要查询的字段前指定
-
号
book_order_by=models.Books.objects.values('title').order_by('title') #默认升序
book_order_by=models.Books.objects.values('title').order_by('-title') # - 号降序
book_order_by =models.Books.objects.all().order_by('title')
book_order_by = models.Books.objects.all().order_by('-age')
10.reverse( ) : 排序
- 对查询结果进行反向排序
- 反转的前提是数据已经排过序. 没排过序reverse将不起作用.
book_reverse = models.Books.objects.all().order_by('title').reverse() #先进行排序,在反转
book_reverse = models.Books.objects.all().order_by('-title').reverse()
11.count():统计个数
- 查询QuerySet内部所包含的数据对象的个数
book_count =models.Books.objects.filter().count()
print(book_count) # 11
bok_count = models.Books.objects.all().count()
print(bok_count) # 11
12.exclude( **kwargs ) : 筛选出不匹配的对象
- 查询与所给筛选条件不匹配的对象, 类似于取反
book_exclude=models.Books.objects.exclude(title='庆余年')
print(book_exclude)
13..exists( ) : 判断数据是否存在
- 如果QuerySet包含数据, 就返回True, 否则返回False
book_exists = models.Books.objects.filter(title='创业邦', price=99).exists()
print(book_exists) # True
box_exists = models.Books.objects.filter(title='青年杂志').exists()
print(box_exists) # False
3.小结
# 返回QuerySet对象的方法
.all() 获取所有.
.filter() 过滤. 不指定参数获取所有. 查询结果不存在返回空的QuerySet对象, 布尔值False
.distinct() 去重. 必须排除主键字段 或 唯一字段才会有意义. filter无法筛选, 一般用在.values() 或 .value_list()后面
.order_by() 排序. 默认升序. 指定降序在字段前加`-`
.reverse() 反转. 只能对排序过后进行反转. 必须在.order_by()之后.
.exclude() 排除. 排除指定的, 展示所有.
# 返回特殊QuerySet对象的方法
.values() 返回QuerySet之内部列表套字典格式. 字典key就是指定的字段.
.values_list() 返回QuerySet之内部列表套元组格式. 元组中值就是指定字段对应的值, 按照指定字段顺序显示.
注意!!!: 指定的字段不存在, 将会抛出异常
# 返回数据对象的方法
.get() 直接获取数据对象. 只能指定一个筛选条件. 如果指定的筛选条件返回的结果不唯一 或者 不存在 抛出异常
.first() 获取QuerySet对象列表内第一个值. 用在QuerySet对象之后, 如果QuerySet对象为空, 再使用它返回None
.last() 获取QuerySet对象列表内最后一个值. 用在QuerySet对象之后, 如果QuerySet对象为空, 再使用它返回None
# 返回数字的方法
.count() 统计QuerySet对象列表内数据对象的个数
# 返回布尔值的方法
.exist() 没软用
四、单表查询之神奇的双下划线(范围查询)
1.参数介绍
参数 | 释义 |
---|---|
__in | 是否在给定的数据集中 |
__gt | 大于 |
__lt | 小于 |
__gte | 大于等于 |
__lte | 小于等于 |
__range | 在...之间, 闭区间 |
__contains | 包含 |
__icontains | 包含(忽略大小写) |
__startswith | 以...开头 |
__endswith | 以...结尾 |
__year | 取出年份(仅限于时间类型) |
__month | 取出月份(仅限于时间类型) |
__day | 取出日期(仅限于时间类型) |
__hour | 取出小时(仅限于时间类型) |
__minute | 取出分钟(仅限于时间类型) |
__second | 取出秒(仅限于时间类型) |
__week_day | 一周的第几天(仅限于时间类型) |
2.示例
# 1.查询价格大于100的书籍
res = models.Books.objects.filter(price__gt=100)
print(res)
print(res.query)
# 2.查询价格小于100的书籍
res = models.Books.objects.filter(price__lt=100)
print(res)
print(res.query)
# 价格大于等于99 小于等于99
res1 = models.Books.objects.filter(price__gte=99)
res2 = models.Books.objects.filter(price__lte=99)
print(res1.query, res2.query)
# 3.查询价格要么是9.9要么是999.66 要么是1999
res = models.Books.objects.filter(price__in=[9.9, 99.99, 1999])
print(res)
"""python对数字不是很敏感 精确度不高 很多时候我们会采取字符串存储数字类型"""
# 4.查询价格在200到1000之间的
res = models.Books.objects.filter(price__range=(200,1000))
print(res.query)
# 5.查询书名中包含字母s的书
res = models.Books.objects.filter(title__contains='s') # 区分大小写
print(res.query)
res = models.Books.objects.filter(title__icontains='s') # 区分大小写
print(res)
# 6.查询出版日期是2021的书
res = models.Books.objects.filter(publish_time__year=2021)
print(res.query)
# 7.查询出版日期是3月的书
res = models.Books.objects.filter(publish_time__month=3)
print(res)
3.小结
# 注意: 争对字段使用. 如: field__gt
__gt __lt __gte __glt
__in=[] __range=[start, stop]
__contains __icontains i全称忽略ignore
__startswith __istartswith
__endswith __iendswith
__year='2020' __year=2020
__month='1' __month=1
__day='20' __day=20
五.拓展
1.查看内部封装的sql语句的2种形式
# 第一种: QuerySet.query
user_queryset = models.User.objects.values_list('name', 'age')
print(user_queryset.query) # SELECT `app01_user`.`name`, `app01_user`.`age` FROM `app01_user`
# 第二种: 执行脚本时打印日志显示到终端. 复制以下日志内容到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',
},
}
}
2.QuerySet其他特性
QuerySet 是可迭代的,比如:
es = models.Books.objects.all()
for e in es:
print({'书名': e.title, '价格': e.price})
QuerySet 支持切片 Entry.objects.all()[:10] 取出10条,可以节省内存
es = models.Books.objects.all()[:2]
print(es) # <QuerySet [<Books: Books object (9)>, <Books: Books object (10)>]>
用 len(es) 可以得到Entry的数量,但是推荐用 Entry.objects.count()来查询数量
es = models.Books.objects.all()
print(len(es))
list(es) 可以强行将 QuerySet 变成 列表
es = models.Books.objects.all()[:2] #前两条
print(list(es))
QuerySet 不支持负索引
book_index = models.Books.objects.all().reverse()[:2] # 最后两条
print(book_index)
box_index = models.Books.objects.filter().reverse()[0] # 最后一条
print(box_index)
bok_index =models.Books.objects.order_by('-price')[:1]
print(bok_index)
QuerySet 是可以用pickle序列化到硬盘再读取出来的
>>> import pickle
>>> query = pickle.loads(s) # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query # Restore the original 'query'.
版权声明:
作者:淘小欣
链接:https://blog.taoxiaoxin.club/150.html
来源:淘小欣的博客
文章版权归作者所有,未经允许请勿转载。
THE END
0
二维码
海报
Django单表操作
一.Django 测试环境搭建
当你只是想测试django中的某一个py文件内容 那么你可以不用书写前后端交互的形式, 而是直接写一个测试脚本即可:
1.方式一
使用脚本形……

共有 0 条评论