目录标题
1.模型层测试环境的准备
1.方式一:
1.首先在项目中创建一个空的测试的.py文件,或者用项目自带的test.py测试文件
2.在测试文件中写入固定代码
import os
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'book.settings')
import django
django.setup()
"""
在这里进行orm操作
"""
if __name__ == '__main__':
main()
2.方式二:
直接用pycharm自带的测试工具:Python console
二:ORM查询常见关键字(必会13条)
1.filter()筛选数据,返回Queryset列表套数据对象
- 括号中不写条件默认查询所有数据
- 括号内可以写多个查询条件,并用逗号隔开,默认是and关系
models.User.objects.filter()
models.User.objects.filter(name='jason', age = '18')
2.all()查询所有的数据,返回一个Queryset,列表套数据对象
models.User.objects.all()
3.first()获取Queryset中的第一个数据对象,如果没有结果,则返回None
models.User.objects.filter(name='jason').first()
4.last()获取Queryset中的第一个数据对象,如果没有结果,则返回None
models.User.objects.filter(name='jasonNB').last()
5.get()直接根据条件查询数据对象,但条件不存在则直接报错
models.User.objects.get(pk=100)
6.values()指定查询字段,结果是Queryset可以看成是列表套字典
models.User.objects.values('name','age')
7.lvalues_list()指定查询字段,结果是Queryset可以看成是列表套字典
models.User.objects.values_list('name','join_time')
8.order_by()指定字段排序,默认是升序,在字段前面加上符号位降序,支持多字段排序
res = models.User.objects.order_by('age') # 升序
res = models.User.objects.order_by('-age','name') # 降序
9.count() 统计orm查询之后的结果数量
models.User.objects.all().count()
10.distinct() 去重,必须是所有字段都相同的数据
models.User.objects.all().distinct()
11.exclude() 括号中的条件取反查询数据,Queryset列表套数据对象
models.User.objects.exclude(pk=1)
12.reverse() 对已经排序的结果颠倒处理
models.User.objects.all().order_by('age').reverse()
13.exists() 判断查询的结果集是否有数据 返回布尔值(了解即可)
models.User.objects.filter(name='jason').exists()
14.raw() 括号中可以直接写sql语句
models.User.objects.raw('select * from app01_user')
三:双下划线查询
1.比较运算符
1.字段__gt 大于
2.字段__lt 小于
3.字段__gte 大于等于
4.字段__lte 小于等于
models.User.objects.filter(age__gt=20)
models.User.objects.filter(age__lt=20)
2.成员运算符
字段__in
models.User.objects.filter(name__in=['jason','tony','osacr'])
3.范围查询(数字)
字段__range
models.User.objects.filter(age__range=(20, 30))
4.模糊查询
字段__contains 不忽略大小写
字段__icontains 忽略大小写
models.User.objects.filter(name__contains='j')
models.User.objects.filter(name__icontains='j')
5.日期处理
字段__year
字段_month
字段__day
res = models.User.objects.filter(join_time__year=2020)
res = models.User.objects.filter(join_time__month=9)
四:查看orm底层sql语句
1.方式一:如果是Queryse对象,直接点query查看
res = models.User.objects.raw('select * from table User')
print(res.query)
# select * from table User
2.方式二:配置文件中配置,打印所有的orm操作对应的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',
},
}
}
五:外键字段数据操作
1.如何给表中的外键字段添加数据值
方式一:直接给外键字段添加数据值
models.Book.objects.create(title='python从入门到放弃',price=29800.88,publish_id=1)
方式二:间接使用外键虚拟字段添加数据对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='Golang',price=39888.88,publish=publish_obj)
2.add() 添加数据
括号内既可以填写数字值,也可以填写数据对象,支持多个
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.add(1) # 朝第三张关系表添加数据
book_obj.authors.add(2,3) # 朝第三张关系表添加数据
book_obj.authors.add(author_obj1)
book_obj.authors.add(author_obj1,author_obj2)
3.remove() 删除数据
括号内既可以填写数字值,亦可以填写数据对象 支持多个
book_obj.authors.remove(1)
book_obj.authors.remove(2, 3)
book_obj.authors.remove(author_obj1)
book_obj.authors.remove(author_obj1,author_obj2)
4.set() 修改数据
括号内必须是可迭代对象
book_obj.authors.set([2,])
book_obj.authors.set([2,3])
book_obj.authors.set([author_obj1, ])
book_obj.authors.set([author_obj1, author_obj2])
5.clear() 清空指定数据
book_obj.authors.clear()
六:正反向概念
1.核心:外键字段在哪张表中
2.正向查询:外键字段所在表查询外键字段对应的表
3.反向查询:外键字段对应的表查询外键字段所在表
orm跨表查询的口诀:正向查询按 ’ 外键字段’,反向查询按 ‘表名小写’
七:基于对象的跨表查询(子查询)
1.正向查询案例
# 1.查询主键为1的书籍对应的出版社
book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.publish)
# 2.查询主键为3的书籍对应的作者(书>>>作者)
book_obj = models.Book.objects.filter(pk=3).first()
print(book_obj.authors) # app01.Author.None
print(book_obj.authors.all())
# 3.查询jason的作者详情
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.author_detail)
2.反向查询案例
# 4.查询南方出版社出版的书籍
publish_obj = models.Publish.objects.filter(name='南方出版社').first()
print(publish_obj.book_set.all())
# 5.查询jason写过的书
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set) # app01.Book.None
print(author_obj.book_set.all())
# 6.查询电话是110的作者
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
print(author_detail_obj.author)
八:基于双下划线的跨表查询(连表操作)
1.正向查询案例
# 1.查询主键为1的书籍对应的出版社名称及书名
res = models.Book.objects.filter(pk=1).values('publish__name','title')
print(res)
# 2.查询主键为3的书籍对应的作者姓名及书名
res = models.Book.objects.filter(pk=3).values('authors__name', 'title')
print(res)
# 3.查询jason的作者的电话号码和地址
res = models.Author.objects.filter(name='jason').values('author_detail__phone','author_detail__addr')
print(res)
2.反向查询案例
'''基于双下划线的反向跨表查询'''
# 4.查询南方出版社出版的书籍名称和价格
res = models.Publish.objects.filter(name='南方出版社').values('book__title','book__price')
# print(res)
# 5.查询jason写过的书的名称和日期
res = models.Author.objects.filter(name='jason').values('book__title','book__publish_time')
# print(res)
# 6.查询电话是110的作者姓名和年龄
res = models.AuthorDetail.objects.filter(phone=110).values('author__name','author__age')
print(res)
3.思考拓展
# 7.查询主键为1的书籍对应的作者电话号码
res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
print(res)
九:创建数据的两种方式
1.方式一
models.User.objects.create(name='jason', age=88)
2.方式二:
user_obj = models.User(name='oscar', age=24)
user_obj.save()