- 如何配置测试脚本
- 必知必会13条
- 1 all() 查询所有
- 2 filter() 筛选 相当于你原生sql语句里面的 where关键字
- 3 get() 筛选 获取的是数据对象本身 条件不存在直接报错 并且只能查询一个
- 4 first() 取queryset中第一个数据对象 数据对象
- 5 last() 取queryset中最后一个数据对象 数据对象
- 6 count() 统计数据的个数 数字
- 7 values() 获取数据对象中指定的字段值 可以多个 queryset 列表套字典
- 8 values_list() 获取数据对象中指定字段的值 可以有多个 queryset 列表套元组
- 9 order_by() 按照指定的字段排序
- 10 reverse() 颠倒顺序 前提是颠倒的对象必须有顺序(前提排序之后才能颠倒顺序)
- 11 exclude() 排除什么什么之外 queryset对象
- 12 exists() 判断查询结果是否有值 返回一个布尔值
- 13 distinct() 对查询结果进行去重操作 去重的前提:数据必须是完全相同的情况下 才能去重
- 神奇的双下划线查询
- 一对多字段的增删改查
- 多对多字段数据的增删改查
- 跨表查询
如何配置测试脚本
第一种
直接在某一应用下的tests文件中写下内容(去manage.py拷贝前四行代码)
然后自己写两行代码即可
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
import django
django.setup()
# 一定要等待测试脚本搭建完毕之后 才能导入django文件进行测试
from app01 import models
第二种
直接新建一个任意名称的py文件 在里面也写上面的配置 也可以配置
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
import django
django.setup()
# 一定要等待测试脚本搭建完毕之后 才能导入django文件进行测试
from app01 import models
给表创建数据的两种方式
方式一 (create方法)
book_obj = models.Books.objects.create(title='水浒传',price=333,publish_date=date.today())
方式二 (利用对象的绑定方法)
book_obj = models.Books(title='西游记',price=666,publish_date='2000-1-22')
book_obj.save() # 该方法不推荐使用 推荐使用queryset方法
# 利用对象的修改 内部其实是重头到尾将数据的所有字段都重新写一遍
查询
一
res = models.Books.objects.filter(pk=1)
print(res)
print(res.query)
'''
pk会自动帮你查找到当前表的主键字段 所以后期我们都是用pk来指代主键字段
filter查询出来的结果是一个Queryset对象
1.只要是queryset对象就可以无限制的调用queryset的方法
2.只要是queryset对象就可以点query查看当前结果内部对应的sql语句
'''
二
book_obj = models.Books.objects.get(pk=1)
print(book_obj)
'''
get和filter区别
1.filter获取到的是一个queryset对象 类似于一个列表
当条件不存在会返回空
2.get获取的直接就是数据对象本身
当条件不存在会报错
'''
删除 (一般不使用)
一 利用queryset
方法 delete()
models.Books.boject.filter(pk=3).delete()
二 对象方法
book_obj = models.Books.objects.get(pk=3)
book_obj.delete()
Django终端打印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',
},
}
}
必知必会13条
orm
语句的查询默认都是惰性查询
只有当你真正要使用数据的时候才执行orm
语句
1 all() 查询所有
models.Books.objects.all()
2 filter() 筛选 相当于你原生sql
语句里面的 where关键字
res = models.Books.objects.filter(pk=1,title=‘三’)
支持多个参数 并且是and关系
3 get() 筛选 获取的是数据对象本身 条件不存在直接报错 并且只能查询一个
res = models.Book.objects.get(pk=1)
4 first() 取queryset
中第一个数据对象 数据对象
res = models.Book.objects.filter(title=‘西游记’).first()
5 last() 取queryset
中最后一个数据对象 数据对象
res = models.Book.objects.filter(title=‘西游记’).last()
6 count() 统计数据的个数 数字
num = models.Books.ojects.count()
7 values() 获取数据对象中指定的字段值 可以多个 queryset
列表套字典
res = models.Books.objects.values(‘title’,‘price’)
8 values_list() 获取数据对象中指定字段的值 可以有多个 queryset
列表套元组
res = models.Books.objects.values_list(‘title’,‘price’)
9 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’)
10 reverse() 颠倒顺序 前提是颠倒的对象必须有顺序(前提排序之后才能颠倒顺序)
res = models.Books.objects.all()
res1 = models.Books.objects.all().reverse()
11 exclude() 排除什么什么之外 queryset
对象
res = models.Books.objects.all().exclude(title=‘三国演义’)
12 exists() 判断查询结果是否有值 返回一个布尔值
res = models.Books.objcts.filter(pk=1).exists()
该方法其实不需要使用 因为数据本身自带布尔值
13 distinct() 对查询结果进行去重操作 去重的前提:数据必须是完全相同的情况下 才能去重
res = models.Books.objects.values(‘title’,‘price’).distinct()
神奇的双下划线查询
大于 __gt
res = models.Books.objects.filter(price__gt=500)
小于 __lt
res = models.Books.objects.filter(price__lt=500)
大于等于 __gte
res = models.Books.objects.filter(price__gte=500)
小于等于 __lte
res = models.Books.objects.filter(price__lte=500)
或者 __in
res = models.Books.objects.filter(price__in=[100,200])
之间 __range
(顾头顾尾)
res = models.Books.objects.filter(price__range=(200,800))
日期
年份 __year
res = models.Books.objects.filter(price_date_year='2019')
月份 __month
res = models.Books.objects.filter(price_date__month='1')
以什么开头
__startswith
以什么结尾
__endswith
包含
__contains
(区分大小写)
__icontains
(不区分大小写)
创建表
class Books(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish_date = models.DateField(auto_now_add=True)
'''
自动创建时间
auto_now: 每次修改数据的时候都会修改时间 展示最近修改的时间
auto_now_add:当数据创建出来的时候 会自动将创建时间记录下来
'''
authors = models.ManyToManyField(to='Author')
publish = models.ForeignKey(to='Publish')
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=64)
class Author(models.Model):
name = models.CharField(max_length=32)
email = models.EmailField() # 对应到数据库中仅仅是varchar(254) 没有任何限制条件 该字段只要是字符串就行
# 仅仅是为了表达语义 需要后期借助校验性组件限制
author_detail = models.OneToOneField(to='AuthorDetail')
class AuthorDetail(models.Model):
phone = models.CharField(max_length=32)
addr = models.CharField(max_length=64)
一对多字段的增删改查
增
第一种
models.Book.objects.create(title=‘三国演义’,price=223,publish,id=1)
直接传表里的实际对象 publish_id
第二种
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Books.objects.create(title='红楼梦',price=444,publish=publish_obj)
改
第一种
models.Books.objects.filter(pk=1).update(publish=2)
第二种
publish_obj = models.Publish.object.filter(pk=1),first()
models.Book.objects.filter(pk=1).update(publish_id=publish)
删
models.Publish.objects.filter(pk=1).delete() # 默认是级联删除 级联更新
多对多字段数据的增删改查
增
book_obj = models.Book.object.filter(pk=2),first()
print(book_obj.publish) 点外键字段可能会获取到外键关联的数据对象
book_obj.authors.add(1) #在第三张表里给书籍绑定一个主键为1的作者
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
book_obj.authors.add(author_obj,author1)
改
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.set((1,3))
'''
set修改多对多关系表中的数据
即可一串数字也可以传对象
但是需要注意的是括号内必须是可迭代对象
都支持多个
'''
删
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.remove(1)
清空
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.authors.clear()
跨表查询
基于对象的跨表查询 子查询
boook_obj = models.Book.objects.filter(pk=2).first()
print(book_obj.publish)
print(book_obj.publish.name)
book_obj = models.Book.objetcs.filter(pk=4).first()
print(book_obj.authors.all())
什么时候加all
当正向查询点击外键字段数据有多个的情况下 需要加all()
app01.Author.None 一旦看见该结果 只需加.all()即可
基于双下划线的链表查询 多表联查
res = models.Book.objets.filter(pk=2).values('publish_name')
models.Book.objects.filter(pk=2).values('authors__name')
models.Author.objects.filter(book__id=2).values('name')
res = models.Book.objet.filter(pk=2).values('authors__author_detail__phone')
models.Book.objects.filter(pk=2).values('外键字段1__外键字段2__外键字段3...') # 基于该方法可以无限跨表
正反向查询
关系字段在谁哪 由谁查谁就是正向
如果关系字段不在 就是反向
正向查询按字段
反向查询按表名小写 + _set
一对多 加 _set
多对多 加 _set
一对一 不加