1.queryset是查询集,就是传到服务器上的url里面的内容。django会对查询返回的结果集queryset进行缓存,这里是为了提高查询效率。
也就是说,在你创建一个queryset对象的时候,django并不会立即向数据库发出查询命令,只有在你需要用到这个queryset的时候才会去数据库查询。
2.objects是django实现的mvc框架中的数据层(model)m,django中的模型类都有一个objects对象,它是一个django中定义的queryset类型的对象,
它包含了模型对象的实例。简单的说,objects是单个对象,queryset是许多对象。
queryset可以被构造,过滤,切片,作为参数传递,这些行为都不会对数据库进行操作。只要你查询的时候才真正的操作数据库。
django测试环境搭建
1.pycharm连接数据库都需要提前下载对应的驱动
2.自带的sqlite3对日期格式数据不敏感
# 方式1:任意创建一个py文件,在该文件内书写固定的配置
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dj0302.settings")
import django
django.setup()
# 方式2:直接使用pycharm提供的python console
单表查询关键字
QuerySet对象常用方法
query # 查看orm内部对应的SQL语句
# 增
# res=models.Books.objects.create(title='三国演义',price=944.28)
# print(res.title)
'''create返回值就是当前被创建的数据对象'''
# 查
# res=models.Books.objects.all()
# print(res.query)
# res=models.Books.objects.filter()
# print(res.query)
# res=models.Books.objects.filter(title='ldb')
# print(res)
'''filter括号内可以放多个参数 默认是and关系 推荐使用 条件不符合不会报错'''
# res=models.Books.objects.get(title='ldb')
# print(res)
'''get括号内可以放多个参数 默认是and关系 不推荐使用 条件不符合直接报错'''
# 改
# res=models.Books.objects.filter(pk=1).update(price=666.66)
# print(res) # 返回值是受影响的行数
# book_obj=models.Books.objects.filter(pk=5).first()
# book_obj.price=500.55
# book_obj.save() # 效率低(所有字段重新写一遍)
'''pk能够自动查找到当前表的主键字段 不需要查看当前表主键字段名'''
# 删
# models.Books.objects.filter(pk=1).delete()
# 1.first() 取第一个数据对象
# res=models.Books.objects.all().first()
# res1=models.Books.objects.all()[0]
# res2=models.Books.objects.all()[0:2]
# print(res,res1,res2)
'''queryset对象还支持切片操作 但是只能填正数'''
# 2.last() 取最后一个数据对象
# res=models.Books.objects.all().last()
# print(res)
# 3.values() 获取数据指定字段的值
# res=models.Books.objects.all().values('title','publish_time')
# res1=models.Books.objects.values('title','publish_time')
# print(res,res1)
'''all()加不加都表示所有数据 values获取的结果 类似于列表套字典'''
# 4.values_list() 获取数据指定字段的值
# res=models.Books.objects.values_list('title','publish_time')
# print(res)
'''values_list获取的结果 类似于列表套元组'''
# 5.order_by() 排序
# res=models.Books.objects.order_by('price') # 默认是升序
# print(res)
# res=models.Books.objects.order_by('-price') # 减号降序
# print(res)
# 6.count() 计数
# res=models.Books.objects.count() # 统计数据条数
# print(res)
# 7.distinct() 去重
# res=models.Books.objects.values('title').distinct()
# print(res)
# 8.exclude() 排除什么在外 取反操作
# res=models.Books.objects.exclude(title='三国演义')
# print(res.query)
# 9.reverse() 反转
# res=models.Books.objects.order_by('price').reverse()
# print(res)
'''reverse需要先排序之后才能反转'''
# 10.exists() 判断是否有数据 返回布尔值
# res=models.Books.objects.exists()
# print(res)
神奇的双下划线查询(范围查询)
# 1.查询价格大于700的书籍
# res=models.Books.objects.filter(price__gt=700)
# print(res)
# print(res.query)
# 2.查询价格小于700的书籍
# res=models.Books.objects.filter(price__lt=700)
# print(res)
# 3.查询书名是红楼梦,三国演义的书籍
# res=models.Books.objects.filter(title__in=['红楼梦','三国演义'])
# print(res)
# 4.查询价格在600到700之间
# res=models.Books.objects.filter(price__range=(500,800))
# print(res)
# 5.查询书名中包含字母s的书
# res=models.Books.objects.filter(title__contains='s') # 区分大小写
# print(res)
# res=models.Books.objects.filter(title__icontains='s') # 不区分大小写
# print(res)
# 6.查询出版日期是2021的书
# res=models.Books.objects.filter(publish_time__year=2021)
# print(res)
# 7.查询出版日期是3月的书
# res=models.Books.objects.filter(publish_time__month=3)
# print(res)
图书管理系统表设计
'''
auto_now
修改数据会自动修改为当前时间
auto_now_add
是创建数据的时间 修改数据不会自动修改时间
'''
class Book(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(verbose_name='出版日期',auto_now_add=True)
# 书籍和出版社是一对多关系 外键字段建在多的一方
publish=models.ForeignKey(to='Publish')
# 书籍和作者是多对多关系 外键字段建在查询频率较高的表中
authors=models.ManyToManyField(to='Author')
class Publish(models.Model):
title=models.CharField(verbose_name='出版社名称',max_length=32)
addr=models.CharField(verbose_name='出版社地址',max_length=128)
email=models.EmailField(verbose_name='邮箱')
class Author(models.Model):
name=models.CharField(verbose_name='姓名',max_length=32)
age=models.IntegerField(verbose_name='年龄')
# 作者和作者详情是一对一的关系 外键字段建在查询频率较高的表中
author_detail=models.OneToOneField(to='AuthorDetail')
class AuthorDetail(models.Model):
phone=models.BigIntegerField(verbose_name='电话')
addr=models.CharField(verbose_name='地址',max_length=32)
'''
作者详情表
作者表
出版社表
书籍表和关系表通过orm实现
'''
外键字段操作
# 直接传主键值
# models.Book.objects.create(title='蛙',price=98.55,publish_id=1)
# 传数据对象
# publish_obj=models.Publish.objects.filter(pk=1).first()
# models.Book.objects.create(title='追风筝的人',price=65.25,publish=publish_obj)
# 修改数据
# models.Book.objects.filter(pk=1).update(publish_id=2)
# publish_obj=models.Publish.objects.filter(pk=3).first()
# models.Book.objects.filter(pk=2).update(publish=publish_obj)
'''多对多外键字段'''
# 增
# book_obj=models.Book.objects.filter(pk=3).first()
# 主键值
# book_obj.authors.add(5)
# 作者对象
# author_obj=models.Author.objects.filter(pk=6).first()
# book_obj.authors.add(author_obj)
# 括号内支持传多个参数
# book_obj.authors.add(6,7)
# author_obj1=models.Author.objects.filter(pk=5).first()
# author_obj2=models.Author.objects.filter(pk=7).first()
# book_obj.authors.add(author_obj1,author_obj2)
# 改
# book_obj=models.Book.objects.filter(pk=2).first()
'''整形不能被迭代 列表、元组等容器类型才能被迭代'''
# book_obj.authors.set([7,]) # 列表
# book_obj.authors.set((5,6)) # 元组
# book_obj.authors.set([author_obj1, ])
# book_obj.authors.set([author_obj1, author_obj2])
# 删
# book_obj.authors.remove(6)
# book_obj.authors.remove(5,6)
# book_obj.authors.remove(author_obj1,author_obj23)
# 清空
# book_obj.authors.clear() # 去第三张关系表中删除所有跟书籍对应的记录
'''
add()
remove()
括号内既可以传数字也可以传对象 逗号隔开即可
set()
括号内必须传可迭代对象 可迭代对象内既可以传数字也可以传对象 支持多个
clear()
清空操作 无需传值
'''
跨表查询理论
正向
从有外键字段的表查与其有关联的表就是正向
反向
与正向查询相反,从没有外键字段的表查
# 就是判断你是否有关联的外键字段
'''
正向查询按外键字段
反向查询按表名小写加_set
'''
基于对象的跨表查询
# 连表操作(子查询)
'''
1.先查询出一个对象
2.基于对象点正反向字段
'''
反向查询表名小写加_set
查询的对象可能有多个情况
查询的对象只有一个的情况不需要加
#########################################################################
# 基于对象的跨表查询
'''正向查询'''
# 1.查询三国演义对应的出版社名称
# book_obj=models.Book.objects.filter(title='三国演义').first()
# res=book_obj.publish
# print(res)
# 2.查询蛙人对应的作者
# book_obj=models.Book.objects.filter(title='蛙').first()
# res=book_obj.authors.all()
# print(res)
# 3.查询ldb的地址
# author_obj=models.Author.objects.filter(name='ldb').first()
# res=author_obj.author_detail
# print(res.addr,res.phone)
'''反向查询'''
# 4.查询东方出版社出版过的书籍
# publish_obj=models.Publish.objects.filter(title='东方出版社').first()
# res=publish_obj.book_set.all()
# print(res)
# 5.查询ldb写过的书
# author_obj=models.Author.objects.filter(name='ldb').first()
# res=author_obj.book_set.all()
# print(res)
'''反向查询一对一情况不需要加_set'''
# 6.查询电话是2121515的作者姓名
# author_detail_obj=models.AuthorDetail.objects.filter(phone=2121515).first()
# res=author_detail_obj.author
# print(res.name,res.age)
'''
总结
正向查询对象.外键
反向查询对象.表名小写加_set
'''
# 连表操作(inner join)
######################################################################
# 基于双下划线查询
# 1.查询三国演义对应的出版社名称
# res=models.Book.objects.filter(title='三国演义').values('publish__title')
# print(res.query)
# 2.查询蛙对应的作者名字和年龄
# res=models.Book.objects.filter(title='蛙').values('authors__name','authors__age')
# print(res)
# 3.查询ldb的地址
# res=models.Author.objects.filter(name='ldb').values('author_detail__addr')
# print(res)
# 1.查询三国演义对应的出版社名称
# res=models.Publish.objects.filter(book__title='三国演义').values('title')
# print(res.query)
# 2.查询蛙对应的作者名字和年龄
# res=models.Author.objects.filter(book__title='蛙').values('name','age')
# print(res)
# 3.查询ldb的地址
# res=models.AuthorDetail.objects.filter(author__name='ldb').values('addr')
# print(res)
# 查询三国演义对应的作者的电话和地址
# res=models.Book.objects.filter(title='三国演义').values('authors__author_detail__phone','authors__author_detail__addr')
# print(res)