Day 53 DjangoORM数据操作

DjangoORM数据操作

配置测试脚本

from django.test import TestCase
import os

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")

    import django
    django.setup()

创建数据

我们现在models文件中创建好Book,Publish,Author,AuthorDetail这四张表

create方法

models.AuthorDetail.objects.create(phone='110', email='[email protected]')models.AuthorDetail.objects.create(phone='120', email='[email protected]')models.Author.objects.create(name='冯*内古特', age=80, author_detail_id=1)models.Author.objects.create(name='菲茨杰拉德', age=44, author_detail_id=2)models.Book.objects.create(title='了不起的盖茨比', price=28.8, book_type='文学', publish_id=2)

修改数据

pk会自动帮你查找到当前表的主键字段,所以后期我们都是用pk来指代主键字段

filter查询出来的结果是一个Queryset对象

  1. 只要是queryset对象就可以无限制的调用queryset的方法

    res = models.Books.objects.filter(pk=1).filter().filter().filter().filter()

  2. 只要是queryset对象就可以点query查看当前结果内部对应的sql语句

    res.query

方式一

models.Book.objects.filter(pk=2).update(price=29.8)

方式二(不推荐使用)

# 利用对象的修改 内部其实是重头到位将数据的所有字段都重新写一遍
book_obj = models.Books.objects.get(pk=1)
book_obj.price = 28.8
book_obj.save()

get和filter的区别

  1. filter获取到的是一个queryset对象,类似于一个列表

  2. get获取到的直接就是数据对象本身

    当条件不存在的情况下
    filter不报错直接返回一个空 推荐使用filter方法
    get直接报错 所以不推荐使用get方法

删除数据

  1. 利用queryset方法 delete()
models.Book.objects.filter(pk=3).delete()
  1. 对象方法
book_obj = models.Book.objects.get(pk=3)
book_obj.delete()

查询数据

13个方法

方法 作用 示例
all() 查询所有 models.Book.objects.all()
filter() 筛选 models.Book.objects.filter(pk=1)
get() 筛选(不存在会报错) models.Book.objects.get(pk=1)
first() 取queryset第一个数据对象 models.Book.objects.filter(publish_id=2).first()
last() 取queryset最后一个数据对象 models.Book.objects.filter(publish_id=2).last()
count() 统计数据个数 models.Book.objects.count()
values() 获取指定字段的值(列表套字典) models.Book.objects.values('title', 'price')
values_list() 获取指定字段的值(列表套元组) models.Book.objects.values_list('title', 'price')
order_by() 按照指定的字段排序 models.Book.objects.all().order_by('price') 字段前面加符号表示降序
reverse() 颠倒顺序(前提是已经排好序) models.Book.objects.all().order_by('price').reverse()
exclude() 排除指定的字段的值 models.Book.objects.all().excl(title='2081')
exists() 判断查询结果是否有值 models.Book.objects.filter(pk=1).exists()
diistinct() 对查询结果进行去重 models.Book.objects.values('title', 'price').distinct()

双下划线

# 查询价格大于30的书籍
res = models.Book.objects.filter(price__gt=30)
print(res)
# 查询价格小于30的书籍
res = models.Book.objects.filter(price__lt=30)
print(res)
# 查询价格大于等于30的书籍
# 对数字精确度不敏感?
res = models.Book.objects.filter(price__gte=30)
print(res)
# 查询价格小于等于30的书籍
res = models.Book.objects.filter(price__lte=30)
print(res)
# 查询价格是20或者30或者50的书籍
res = models.Book.objects.filter(price__in=[20, 30, 50])
print(res)
# 查询价格在20到50之间的书籍(顾头又顾尾)
res = models.Book.objects.filter(price__range=(20, 50))
print(res)
# 查询注册日期是2019的用户
res = models.User.objects.filter(register_time__year='2019')
print(res)
# 查询注册日期是11月份的用户
res = models.User.objects.filter(register_time__month='11')
# 模糊查询
# 查询书籍是与霍开头的书
res = models.Book.objects.filter(title__startswith='霍')
print(res)
# 查询书籍是以情结尾的书
res = models.Book.objects.filter(title__endswith='情')
print(res)
# 查询书籍中含有p字母的书
res = models.Book.objects.filter(title__contains='p')  # 默认区分大小写
res = model.Book.objects.filter(title__icontains='P')  # 忽略大小写
print(res)

一对多字段数据的增删改查

# 方式一
models.Book.objects.create(title='了不起的盖茨比', price=28.8, book_type='文学', publish_id=2)
# 方式二
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='了不起的盖茨比', price=28.8, book_type='文学', publish=publish_obj)

# 方式一
models.Book.objects.filter(pk=2).update(publish_id=1)
# 方式二
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)

models.Publish.objects.filter(pk=1).delete()  # 默认就是级联删除 级联更新

多对多字段数据的增删改查

# 方式一
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.add(1,3)  # book_obj.author已经跨到第三张表了
# 方式二
book_obj = models.Book.objects.filter(pk=2).first()
author_obj = models.Book.objects.filter(pk=1).first()
author_obj1 = models.Book.objects.filter(pk=3).first()
book_obj.author.add(author_obj, author_obj1)

add方法能够朝第三张关系表添加数据

​ 即支持传数字

​ add(1, 3)

​ 也支持传对象

​ add(author_obj, author_obj1)

​ 并且可以多个

# 方式一
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.set([4,5])
# 方式二
book_obj = models.Book.objects.filter(pk=2).first()
author_obj = models.Book.objects.filter(pk=4).first()
author_obj1 = models.Book.objects.filter(pk=5).first()
book_obj.author.set((author_obj, author_obj1))

set修改多对多关系表中的数据

既可以传数字也可以传对象

但是需要注意的是括号内必须是迭代对象

都支持多个

# 方式一
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.remove(1,3)  # book_obj.author已经跨到第三张表了
# 方式二
book_obj = models.Book.objects.filter(pk=2).first()
author_obj = models.Book.objects.filter(pk=1).first()
author_obj1 = models.Book.objects.filter(pk=3).first()
book_obj.author.remove(author_obj, author_obj1)

清空

book_obj = models.Book.objects.filter(pk=2).first()
book_obj.author.clear()

clear清空书籍相关的所有记录,括号内不需要传递参数

跨表查询

正反向查询

​ 关系字段在哪张表里,由这张表查另一张表就是正向,否则就是反向

基于对象的跨表查询

  1. 查询书籍主键为2的出版社名称
book_obj = models.Book.objects.filter(pk=2).first()
print(book_obj.publish.name)
  1. 查询书籍主键为4的作者姓名
book_obj = models.Book.objects.filter(pk=2).first()
print(book_obj.author.all().values('name'))
  1. 查询作者是jason的手机号码
author_obj = models.Author.objects.filter().first()
print(author_obj.author_detail.phone)

注意

什么时候要加all

当正向查询点击外键字段数据有多个的情况下,需要.all()

app01.Author.None 一旦看到该结果,只需要加.all()即可

反向查询

  1. 查询出版社是南方出版社出版过的书籍
publish_obj = models.Publish.objects.filter(name='南方出版社').first()
print(publish_obj.book_set.all())
  1. 查询作者是jason写的书籍
author_obj = models.Author.objects.filter(name='jason').first()
print(author_obj.book_set.all())
  1. 查询手机是120的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone='120').first()
author_detail_obj.author_set.name

基于双下划线的跨表查询

  1. 查询书籍pk为2的出版社名称
# 正向
res = models.Book.objects.filter(pk=2).values('publish__name')
print(res)
# 反向
res = models.Publish.objects.filter(book__pk=2).values('name')
print(res)
  1. 查询书籍pk为2的作者姓名和邮箱
# 正向
res = models.Book.objects.filter(pk=2).values('author__name', 'author__email')
print(res)
# 反向
res = models.Author.objects.filter(book__pk=2).values('name', 'email')
print(res)
  1. 查询作者是egon的家庭住址
# 正向
res = models.Author.objects.filter(name='egon').values('author_detail__addr')
print(res)
# 反向
res = models.AuthorDetail.filter(author__name='egon').values('addr')
print(res)
  1. 查询出版社是东方出版社出版过的书的名字
# 反向
res = models.Publish.objects.filter(name='东方出版社').values('book__title')
print(res)
# 正向
res = models.Book.objects.filter(publish__name='东方出版社').values('title')
print(res)
  1. 查询书籍pk是2的作者的手机号
# 正向
res = models.Book.objects.filter(pk=2).values('author__author_detail__phone')
print(res)
# 反向
res = models.Author.objects.filter(book__pk=2).values('author_detail__phone')
print(res)

res = models.AuthorDetail.objects.filter(author__book__pk=2).values('phone')
print(res)

猜你喜欢

转载自www.cnblogs.com/2222bai/p/11946130.html
53