day53 表查询

配置测试脚本

 当你想单独测试django中某一个py文件 你需要手动配置测试脚本

如何配置测试脚本
第一种
  直接在某一个应用下的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

day53 表查询_第1张图片

 创建数据

1.用create创建数据

传时间的时候除了手动写,也可以传入日期

from datetime import date
ctime = date.today()
book_obj = models.Books.objects.create(title='红楼梦',price=333,publish_data=ctime)

 2.用对象的绑定方法

book_obj = models.Books(title='西游记',price='666',publish_data='2000-1-21')
book_obj.save()

 修改数据

# res = models.Books.objects.filter(pk=1)
"""
pk会自动帮你查找到当前表的主键字段 所以后期我们都是用pk来指代主键字段
filter查询出来的结果是一个Queryset对象
1.只要是queryset对象就可以无限制的调用queryset的方法
res = models.Books.objects.filter(pk=1).filter().filter().filter().filter()
2.只要是queryset对象就可以点query查看当前结果内部对应的sql语句
print(res.query)
SELECT `app01_books`.`id`, `app01_books`.`title`, `app01_books`.`price`,
`app01_books`.`publish_date` FROM `app01_books` WHERE `app01_books`.`id` = 1
"""
方式1  利用queryset方法
models.Books.objects.filter(pk=1).update(price=444.66)
方式2 利用对象
book_obj = models.Books.objects.get(pk=1)
book_obj.price = 222.66
book_obj.save() # 该方法不推荐使用 推荐使用queryset方法
利用对象的修改 内部其实是重头到位将数据的所有字段都重新写一遍
"""
get和filter区别
1.filter获取到的是一个queryset对象 类似于一个列表

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

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

 删除数据:

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

在配置文件中添加:可以直接根据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',
        },
    }
}

必知必会13条

    1. all()  查询所有        返回的结果QuerySet对象
    res = models.Books.objects.all()
    print(res)
    """
    orm语句的查询默认都是惰性查询
        只有当你真正要使用数据的时候才会执行orm语句
    """
    2. filter()  筛选 相当于你原生sql语句里面的 where关键字     返回的结果QuerySet对象
    res = models.Books.objects.filter(pk=1,title='')  # 支持多个参数 并且是and关系
    print(res)

    3. get()   筛选  获取的是数据对象本身  条件不存在直接报错  并且查询条件必须是唯一的      数据对象
    res = models.Books.objects.get(title='西游记')
    res1 = models.Books.objects.filter(title='西游记')
    # print(res,res1)
    print(res1)

    4. first()  取queryset中第一个数据对象     数据对象
    res = models.Books.objects.filter(title='西游记').first()
    print(res.price)

    5. last()  取queryset中最后一个数据对象    数据对象
    res = models.Books.objects.filter(title='西游记').last()
    print(res.price)

    6. count()  统计数据的个数   数字
    num = models.Books.objects.count()
    print(type(num))

    7. values()  获取数据对象中指定的字段的值  可以有多个  queryset  列表套字典
    res = models.Books.objects.values('title','price')
    print(res)
    'title': '三国演义', 'price': Decimal('222.66')}, {'title': '红楼梦', 'price': Decimal('888.99')}, {'title': '西游记', 'price': Decimal('444.66')}, {'title': '西游记', 'price': Decimal('666.22')}]>

    8. values_list()  获取数据对象中指定的字段的值  可以有多个  queryset  列表套元祖
    res = models.Books.objects.values_list('title','price')
    print(res)
    '三国演义', Decimal('222.66')), ('红楼梦', Decimal('888.99')), ('西游记', Decimal('444.66')), ('西游记', Decimal('666.22'))]>

    9.order_by()      按照指定的字段排序
    res = models.Books.objects.order_by('price')  # 默认是升序
    res1 = models.Books.objects.all().order_by('price')  # 默认是升序   两者等价 下面的方式 语义更明确
    降序  字段前面加负号
    res1 = models.Books.objects.all().order_by('-price')
    print(res1)

    10.reverse()      颠倒顺序   前提是颠倒的对象必须有顺序(提前排序之后才能颠倒)和order_by连用
    res = models.Books.objects.all()
    res1 = models.Books.objects.all().reverse()
    res2 = models.Books.objects.all().order_by('price')
    res3 = models.Books.objects.all().order_by('price').reverse()
    print(res2,res3)

    11.exclude()      排除什么什么之外   queryset对象
    res = models.Books.objects.all().exclude(title='三国演义')
    print(res)
    , , ]>

    12.exists()      判断查询结果是否有值 返回结果是一个布尔值
    res = models.Books.objects.filter(pk=1).exists()
    print(res)
    该方法其实不需要使用  因为数据本身自带布尔值

    13.distinct()    对查询结果进行去重操作     去重的前提:数据必须是完全相同的情况下 才能够去重(容易忽略主键)
    res = models.Books.objects.values('title','price')
    res = models.Books.objects.values('title','price').distinct()
    print(res)

 

 神奇的双下划线查询

    查询价格大于500的书籍
    res = models.Books.objects.filter(price__gt=500)
    print(res)
查询价格小于400 的书籍 res
= models.Books.objects.filter(price__lt=400) print(res)
查询价格大于等于500
res = models.Books.objects.filter(price__gte=500) print(res)
查询价格小于等于500的书籍 res
= models.Books.objects.filter(price__lte=500) print(res) 查询价格是222或者444或者500的书籍 res = models.Books.objects.filter(price__in=[222,444,500]) print(res) 查询价格在200到800之间的书籍 res = models.Books.objects.filter(price__range=(200,800)) # 顾头顾尾 print(res) 查询出版日期是2019年的书籍 res = models.Books.objects.filter(publish_date__year='2019') print(res)
查询出版日期是1月份的书籍 res
= models.Books.objects.filter(publish_date__month='1') print(res)

 

 模糊查询

MySQL中的模糊查询
关键字 like
模糊匹配的符号
%:匹配任何个数的任意字符
_:匹配一位任意的字符
    查询书籍是以三开头的书
    res = models.Books.objects.filter(title__startswith='')
    print(res)
    查询书籍是以义结尾的书
    res = models.Books.objects.filter(title__endswith='1')
    print(res)
    查询书籍名称中包含游字的书籍
    res = models.Books.objects.filter(title__contains='')
    print(res)

    查询书籍名称中包含字母p的书籍
    res = models.Books.objects.filter(title__contains='p')  # 默认区分大小写
    res = models.Books.objects.filter(title__icontains='p')  # 忽略大小写 加i
    print(res)

 

auto_now:每次修改的数据的时候 都会自动更新修改书籍(展示最新的一次修改时间)
auto_now_add:当数据创建出来的时候 会自动将创建时间记录下来
class Book(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)#会自动写入时间

 

 一对多字段的增删改查

传实际数字,或者传对象

    增
    第一种
    models.Book.objects.create(title='三国演义',price=222.33,publish_id=1)  # 直接传表里面的实际字段 跟数据主键值  publish_id
    第二种
    publish_obj = models.Publish.objects.filter(pk=2).first()
    models.Book.objects.create(title='红楼梦',price=444.33,publish=publish_obj)  # 传虚拟字段  跟数据对象即可

    查

    改
    第一种
    models.Book.objects.filter(pk=1).update(publish_id=2)
    第二种
    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()
    print(book_obj.publish)  # 点外键字段 可能会直接获取到外键关联的数据对象
    给当前这一本书绑定作者
    麻瓜做法  自己直接去操作第三张表
    传数字
    print(book_obj.authors)  # 已经跨到第三张表了
    book_obj.authors.add(1)  # 在第三张表里面给书籍绑定一个主键为1的作者
    book_obj.authors.add(1,2)  # 同时传两个
    传对象
    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    # book_obj.authors.add(author_obj)
    book_obj.authors.add(author_obj,author_obj1)
    """
    add方法 能够朝第三张关系表添加数据
        即支持传数字
            add(1,2)
        也支持传对象
            add(author_obj,author_obj1)
        并且两者都可以是多个
    """

    改 (先删再增,把需要改的删了,再添加)
    book_obj = models.Book.objects.filter(pk=2).first()
    # book_obj.authors.set((1,3))
    # book_obj.authors.set([1,])
    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    book_obj.authors.set((author_obj,author_obj1))
    """
    set修改多对多关系表中的数据
        既可以传数字也可以传对象
        但是需要注意的是括号内必须是可迭代对象
        都支持多个
            set((1,3))
            set((author_obj,author_obj1))
    """

    删
    book_obj = models.Book.objects.filter(pk=2).first()
    book_obj.authors.remove(100)
    book_obj.authors.remove(1,2)
    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    # book_obj.authors.remove(author_obj)
    book_obj.authors.remove(author_obj,author_obj1)
    """
    remove既可以传数字 也可以穿对象
        并且都支持传多个 不需要迭代
            remove(1,2)
            remove(author_obj,author_obj1)
    """
    清空  删除某个数据在第三张表中的所有记录
    book_obj = models.Book.objects.filter(pk=2).first()
    book_obj.authors.clear()#把书籍为2的所有记录都清除了
    """
    clear清空书籍相关所有记录  括号内不需要传递参数 
    """

基于对象的跨表查询

    """
    正反向查询
            关系字段在谁哪 由谁查谁就是正向
            如果关系字段不在 就是反向
        正向查询按字段              .all()  authors.all() 多个情况下
        反向查询按表名小写+ _set   .all()   book_set 多个情况下
    """
    基于对象的跨表查询         子查询  分步操作
    1.查询书籍主键为2的出版社名称
    book_obj = models.Book.objects.filter(pk=2).first()
    print(book_obj.publish)  # 出版社对象
    print(book_obj.publish.name)
    2.查询书籍主键为4的作者姓名
    book_obj = models.Book.objects.filter(pk=4).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)
    print(author_obj.author_detail.phone)
    """
    什么时候需要加all 
    当正向查询点击外键字段数据有多个的情况下 需要.all()
    app01.Author.None  一旦看到该结果 只需要加.all()即可
    """
    4.查询出版社是东方出版社出版过的书籍
    publish_obj = models.Publish.objects.filter(name='东方出版社').first()
    # print(publish_obj.book_set)  # app01.Book.None
    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())  # app01.Book.None

    6.查询手机号是120的作者姓名
    author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
    print(author_detail_obj.author)
    print(author_detail_obj.author.email)
    """
    什么时候反向查询的时候表名小写需要加_set
        一对多
        多对多
    
    一对一不需要加_set
    """

 基于双下划线跨表查询

    """
    inner join
    left join
    right join
    union
    """
    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)


    2.查询书籍pk为2的作者姓名和邮箱
    res = models.Book.objects.filter(pk=2).values('authors__name','authors__email')
    print(res)
    res = models.Author.objects.filter(book__pk=2).values('name','email')
    print(res)
    """
    models后面点的谁 就以谁为基表
    """

    3.查询作者是egon的家庭地址
    res = models.Author.objects.filter(name='egon').values('author_detail__addr')
    print(res)
    res = models.AuthorDetail.objects.filter(author__name='egon').values('addr')
    print(res)


    4.查询出版社是东方出版社出版过的书的名字
    res = models.Publish.objects.filter(name='东方出版社').values('book__title')
    print(res)
    res = models.Book.objects.filter(publish__name='东方出版社').values('title')
    print(res)

    查询书籍pk是2的作者的手机号
    res = models.Book.objects.filter(pk=2).values('authors__author_detail__phone')
    print(res)
    res = models.Author.objects.filter(book__pk=2).values('author_detail__phone')
    print(res)

 

你可能感兴趣的:(day53 表查询)