【2022.9.5】Django框架之(表查询数据准备及测试环境搭建、表查询关键字、外键创建、外键数据增删改查、多表查询(子查询、连表操作))

今日内容概要

  • 表查询数据准备及测试环境搭建
  • 表查询关键字
  • 外键创建
  • 外键数据增删改查
  • 多表查询(子查询、连表操作)

今日内容详细

表查询数据准备及测试环境搭建

  • 1、Django数据库的介绍
1.Django本身的配置文件中自带一个小型数据库(sqlite3)
	该数据库功能非常的有限 并且针对日期类形的数据兼容性很差 一般作为本地测试来用
    考虑到数据库的兼容性 我们可以手动创建MySQL数据库的连接
  • 2、Django切换MySQL数据
1.考虑到数据库的兼容性 我们可以手动创建MySQL数据库的连接切换
 (1) 版本为: Django1.x中 在__init__.py中导入模块
      import pymysql
    pymysql.install_as_MySQLdb()
 (2)版本为: django2.X 3.X 4.X
	 
    可以下载插件 pip版本 install mysqlclient
    

​ 2.下载完毕后 在配置文件中更改数据库MySQL连接配置

  • 3、定义模型类
1.连接完毕后 在MySQL终端已经创好了库 我们直接就可以在models.py中直接写类 创表就可以了


class User(models.Model):
    Uid = models.AutoField(primary_key=True,verbose_name='编号')
    name = models.CharField(max_length=32,verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄')
    join_time = models.DateTimeField(auto_now=True)

"""
verbose_name 是注释的意思

"""
"""
            日期字段重要参数
        auto_now:每次操作数据并保存都会自动更新当前时间
        auto_now_add:只在创建数据的那一刻自动获取当前时间 之后如果不人为更改则不变



"""





  • 4、执行数据库迁移命令/同步命令(模型类>>>表)

    • 1.将models中有关数据库的操作记录下来
      • makemigrations
    • 2.将操作真正影响到数据库中
      • migrate
    • 3.当修改了models中与数据库相关的代码 都必须要重复1、2 步骤的操作
  • 5.模型层测试环境准备

1.方式1:在任意空的py文件中准备环境(tests.py测试文件)
2.然后把manage.py中的部分输入复制过来

import os

def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day9_5.settings')
    import django
    django.setup()

    from app01 import models
    print(models.User.objects.filter())


if __name__ == '__main__':
    main()

    
   

3.方式2:pycharm提供测试环境
	
     python console命令行测试环境  终端关闭整个就结束了  保存不了数据

 

ORM常见查询关键字

  • 1.当需要查询数据主键字段值的时候 可以使用pk忽略掉数据字段真正的名字
  • 2.在模型类中可以定义一个__str__方法 便于后续数据对象被打印展示的是查看方便
  • 3.Queryset中如果是列表套对象那么直接for循环和索引取值但是索引不支持负数
  • 4.虽然queryset支持索引但是当queryset没有数据的时候索引会报错 推荐使用first
  • 5.增、删、改
    • 1.create() 【创建数据 返回值就是当前创建的数据对象、还可以利用类实例化对象然后调用save方法创建】
    • 2.delete()【删除数据】
    • 3.update() 【更新数据】
1.filter()
	筛选数据 返回值是一个QuerySet(可以看成是列表套数据对象)
   	1.括号内不写查询条件 默认就是查询所有
	2.括号内可以填写条件 并且支持多个 逗号隔开 默认是and关系
2.all()
	查询所有数据 返回值是一个QuerySet(可以看成是列表套数据对象)
3.first()
	获取Queryset中第一个数据对象 如果为空则返回None
4.last()
	获取Queryset中最后一个数据对象 如果为空则返回None
5.get()
	直接根据条件查询具体的数据对象 但是条件不存在直接报错 不推荐使用
6.values()
	指定查询字段 结果是Queryset(可以看成是列表套字典数据)
7.values_list()
	指定查询字段 结果是Queryset(可以看成是列表套元组数据)
8.order_by()
	指定字段排序 默认是升序 在字段前加负号则为降序 并且支持多个字段排序
9.count()
	统计orm查询之后结果集中的数据格式
10.distinct()
	针对重复的数据集进行去重 一定要注意数据对象中的主键
11.exclude()
	针对括号内的条件取反进行数据查询 QuerySet(可以看成是列表套数据对象)
12.reverse()
	针对已经排了序的结果集做颠倒
13.exists()
	判断查询结果集是否有数据 返回布尔值 但是几乎不用因为所有数据自带布尔值
14.raw()
	执行SQL语句
 	还可以借助于模块
    from django.db import connection  
    cursor = connection.cursor()  
    cursor.execute("insert into hello_author(name) VALUES ('小明')") 
    cursor.execute("update hello_author set name='小红' WHERE name='小明'")  
    cursor.execute("delete from hello_author where name='小红'")  
    cursor.execute("select * from hello_author")  
    cursor.fetchone()  
    cursor.fetchall()




神奇的双下划线的查询

1.比较运算符
	字段__gt					大于
 	字段__lt					小于
 	字段__gte					大于等于
 	字段__lte					小于等于
2.成员运算符
	字段__in					
3.范围查询(数字)
	字段__range
4.模糊查询
	字段__contains          不忽略大小写
 	字段__icontains			 忽略大小写
5.日期处理
	字段__year
 	字段__month
 	字段__day




查看ORM底层SQL语句

1.方式1
	如果是Queryset对象 那么可以直接点query查看SQL语句
    
2.方式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',
            },
        }
    }

ORM外键字段创建

models.ForeignKey(to='Publish', on_delete=models.CASCADE)
	方式1直接给实际字段添加关联数据值	 publish_id = 1
  	方式2间接使用外键虚拟字段添加数据对象 publish=publish_obj
models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
	方式1直接给实际字段添加关联数据值	 author_detail_id = 1
  	方式2间接使用外键虚拟字段添加数据对象 author_detail=authorDetail_obj
models.ManyToManyField(to='Author')
	add()
    	添加数据  括号内即可以填写数字值也可以填写数据对象 支持多个
 	remove()
    	删除数据  括号内即可以填写数字值也可以填写数据对象 支持多个
   set()
		修改数据  括号内必须是可迭代对象 
	clear()
    	清空指定数据  括号内不需要任何参数



正反向概念

  • 1.正反向的概念核心就在于外键字段在谁手上
  • 2.正向查询
    • 通过书查询出版社 外键字段在书表中
  • 3.反向查询
    • 通过出版社查询书 外键字段不在出版社表中
  • 4.ORM跨表查询口诀>>>:正向查询按外键字段 反向查询按表名小写

基于对象的跨表查询(子查询)

'''基于对象的正向跨表查询'''
# 1.查询主键为1的书籍对应的出版社(书>>>出版社)
# 1.1.先根据条件查询数据对象(先查书籍对象)
book_obj = models.Book.objects.filter(pk=1).first()
# 1.2.以对象为基准 思考正反向概念(书查出版社 外键字段在书表中 所以是正向查询)
print(book_obj.publish)

# 2.查询主键为3的书籍对应的作者(书>>>作者)
# 2.1.先根据条件查询数据对象(先查书籍对象)
book_obj = models.Book.objects.filter(pk=3).first()
# 2.2.以对象为基准 思考正反向概念(书查作者 外键字段在书表中 所以是正向查询)
print(book_obj.authors)  # app01.Author.None
print(book_obj.authors.all())

# 3.查询jason的作者详情
# 3.1.先根据条件查询数据对象
author_obj = models.Author.objects.filter(name='jason').first()
# 3.2.以对象为基准 思考正反向概念
print(author_obj.author_detail)
'''基于对象的反向跨表查询'''
# 4.查询南方出版社出版的书籍
# 4.1.先拿出版社对象
publish_obj = models.Publish.objects.filter(name='南方出版社').first()
# 4.2.思考正反向
# print(publish_obj.book)
# print(publish_obj.book_set)  # app01.Book.None
print(publish_obj.book_set.all())

# 5.查询jason写过的书
# 5.1.先拿作者对象
author_obj = models.Author.objects.filter(name='jason').first()
# 5.2.思考正反向
# print(author_obj.book)
# print(author_obj.book_set)  # app01.Book.None
print(author_obj.book_set.all())

# 6.查询电话是110的作者
# 6.1.先拿作者详情对象
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
# 6.2.思考正反向
print(author_detail_obj.author)



基于双下划线的跨表查询(连表操作)

'''基于双下划线的正向跨表查询'''
# 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)
'''基于双下划线的反向跨表查询'''
# 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)


"""
研究ORM跨表本质
# 7.查询主键为1的书籍对应的作者电话号码
res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
    print(res)
"""


posted @   W日常  阅读(86)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示