计算机基础知识54

 ORM的介绍

# ORM是什么?

        我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(增、删、改、查),而一旦谈到数据的管理操作,就需要用到数据库管理软件,例如mysql、oracle、Microsoft SQL Server等。

# ORM的概念:

        ORM全称Object Relational Mapping,即对象关系映射,是在pymysq之上又进行了一层封装,对于数据的操作,我们无需再去编写原生sql,取代代之的是基于面向对象的思想去编写类、对象、调用相应的方法等,ORM会将其转换/映射成原生SQL然后交给pymysql执行

ORM的使用之数据库迁移

1、创建模型:数据来源于数据库的表,而ORM的模型类对应数据库表

# 创建django项目,新建名为app01的app,在app01的models.py中创建模型
class Employee(models.Model):  # 必须是models.Model的子类
    id=models.AutoField(primary_key=True)
    name=models.CharField(max_length=16)
    gender=models.BooleanField(default=1)
    birth=models.DateField()
    department=models.CharField(max_length=30)
    salary=models.DecimalField(max_digits=10,decimal_places=1)

2、 配置settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',      
    'app01.apps.App01Config',  # django2.x+版本    
    # 'app01',  # django1.x版本]

DATABASES = {         # 删除\注释掉原来的DATABASES配置项,新增下述配置
    'default': {
        'ENGINE': 'django.db.backends.mysql', # 使用mysql数据库
        'NAME': 'db1',          # 要连接的数据库
        'USER': 'root',         # 链接数据库的用于名
        'PASSWORD': '',         # 链接数据库的用于名                  
        'HOST': '127.0.0.1',    # mysql服务监听的ip  
        'PORT': 3306,           # mysql服务监听的端口  
        'ATOMIC_REQUEST': True, #设置为True代表同一个http请求所对应的所有sql都放在一个事务中

3.配置日志:如果想打印orm转换过程中的sql,需要在settings中进行配置日志

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

4、数据库迁移命令

python manage.py makemigrations
python manage.py migrate

 模型层models:表查询

 模型层的表查询:跟数据库打交道的

1、单表查询:

        insert update delete all filter

2、常见的查询方法:

单表操作:     
    1、all()      查询所有数据,索引取值    
    2、filter()   过滤条件查询     
    3、get()      查询数据,查询数据为空的情况直接报错     
    4、last()     取所有数据的最后一条     
    5、values( id,username,password )   取值,列表套字典[{'id':1,'username':...},{...}]     
    6、vallues_list()                   取值,列表套元组,都支持for循环     
    7、pring(res.quert)   查看内部的SQL语句,只有防御的结果是queryset对象的时候才能查看     
    8、distinct()         去重     
    9、order_by( 'id' )   默认情况升序排序;('-id')倒序     
    10、reverse()         翻转     
    11、count()           统计当前表中数据的个数     
    12、exclude(pk=1)     排除在外     
    13、exists()          看数据到底有没有

3、基于双下划线的查询:

res = models.UserInfo.object.filter(age_gt=38).all()
age__gt=1---大于
age__lt=1---小于
age__gte=1---大于等于
age__lte=1---小于等于
ageage__in=[18,40]  年龄在十八或40的,或
age__range=[18,40]  年龄在十八到40的,之间

 # 包含s的数据,模糊查询:   

包含s的数据,模糊查询:
    # select * from userinfor where name like '%s%',
    res = models.UserInfo.object.filter(username__contains='s').all()
    print(res)
    print(res.query)
username__icontains--忽略大小写
username__startswith=='o'--以o开头的
username__endswith=='o'--以o结尾的

# 日期查询:

register_time = models.DateTimeField(auto_now=True,auto_now_add=True,null=True)
auto_now: 修改的时间
auto_now_add: 刚加进去时间
查询时间:查2020年1月份的
filter(register_time__year='2020',register_time__month='01).all()

多表查询(跨表查询)

子查询:分步查询
链表查询:把多个有关系的表拼接成一个大表(虚拟表)
            inner join 
            left join
            right join

基于双下划线的查询

年龄大于35岁的数据:

        res = models.User.objects.filter(age__gt=35)

年龄小于35岁的数据:

        res = models.User.objects.filter(age__lt=35)

大于等于 小于等于:

        res = models.User.objects.filter(age__gte=32)

        res = models.User.objects.filter(age__lte=32)

年龄是18 或者 32 或者40:

        res = models.User.objects.filter(age__in=[18,32,40])

年龄在18到40岁之间的  首尾都要:

        res = models.User.objects.filter(age__range=[18,40])

查询出名字里面含有s的数据  模糊查询:

        res = models.User.objects.filter(name__contains='s')

是否区分大小写  查询出名字里面含有p的数据  区分大小写:

        res = models.User.objects.filter(name__contains='p')

忽略大小写:

        res = models.User.objects.filter(name__icontains='p')

以 'j' 开头或以 'j' 结尾:

       res = models.User.objects.filter(name__startswith='j')
       res1 = models.User.objects.filter(name__endswith='j')

查询出注册时间是 2020 1月:

        res = models.User.objects.filter(register_time__month='1')

        res = models.User.objects.filter(register_time__year='2020')

多表查询前期表准备

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)

    # 一对多
    publish = models.ForeignKey(to='Publish')
    # 多对多
    authors = models.ManyToManyField(to='Author')

class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)
 # varchar(254)  该字段类型不是给models看的 而是给后面我们会学到的校验性组件看的
    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    # 一对一
    author_detail = models.OneToOneField(to='AuthorDetail')

class AuthorDetail(models.Model):
    phone = models.BigIntegerField()  # 电话号码用BigIntegerField或者直接用CharField
    addr = models.CharField(max_length=64)

一对多外键增删改查

# 增:

方式一:直接写实际字段 id
models.Book.objects.create(title='论语',price=899.23,publish_id=1)
models.Book.objects.create(title='聊斋',price=444.23,publish_id=2)
models.Book.objects.create(title='老子',price=333.66,publish_id=1)
方式二:虚拟字段 对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='红楼梦',price=666.23,publish=publish_obj)

# 删:  models.Publish.objects.filter(pk=1).delete()  # 级联删除

# 修改

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)

多对多外键增删改查

# 增,给书籍添加作者:

book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.authors)  # 就类似于你已经到了第三张关系表了
book_obj.authors.add(1)  # 书籍id为1的书籍绑定一个主键为1 的作者
book_obj.authors.add(2,3)

author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
author_obj2 = models.Author.objects.filter(pk=3).first()
book_obj.authors.add(author_obj)
"""add给第三张关系表添加数据,括号内既可以传数字也可以传对象 并且都支持多个"""

# 删:

book_obj.authors.remove(2)
book_obj.authors.remove(1,3)

author_obj = models.Author.objects.filter(pk=2).first()
author_obj1 = models.Author.objects.filter(pk=3).first()
book_obj.authors.remove(author_obj,author_obj1)
"""remove,括号内既可以传数字也可以传对象 并且都支持多个"""

# 修改:

book_obj.authors.set([1,2])  # 括号内必须给一个可迭代对象
book_obj.authors.set([3])  # 括号内必须给一个可迭代对象

author_obj = models.Author.objects.filter(pk=2).first()
author_obj1 = models.Author.objects.filter(pk=3).first()
book_obj.authors.set([author_obj,author_obj1])  # 括号内必须给一个可迭代对象

# 清空,在第三张关系表中清空某个书籍与作者的绑定关系

        book_obj.authors.clear() 

  clear括号内不要加任何参数

正反向的概念

正向:外键字段在我手上那么,我查你就是正向,按 外键字段
反向:外键字段如果不在手上,我查你就是反向,按 表名小写
          book >>>外键字段在书那儿(正向)>>> publish
          publish    >>>外键字段在书那儿(反向)>>>book
 _set

多表查询之子查询

子查询---基于对象的跨表查询

1.查询书籍主键为1的出版社:

book_obj = models.Book.objects.filter(pk=1).first() # 书查出版社 正向
res = book_obj.publish
print(res)
print(res.name)
print(res.addr)

2.查询书籍主键为2的作者:

book_obj = models.Book.objects.filter(pk=2).first()   # 书查作者 正向
res = book_obj.authors   # app01.Author.None
res = book_obj.authors.all()   # 查的多的话要用all()
print(res)

3.查询作者jason的电话号码:

author_obj = models.Author.objects.filter(name='jason').first()
res = author_obj.author_detail
print(res)
print(res.phone)
print(res.addr)

4.查询出版社是东方出版社出版的书:

publish_obj = models.Publish.objects.filter(name='东方出版社').first()  # 出版社查书  反向
res = publish_obj.book_set    # app01.Book.None
res = publish_obj.book_set.all()
print(res)

5.查询作者是jason写过的书:

author_obj = models.Author.objects.filter(name='jason').first() # 作者查书 反向
res = author_obj.book_set  # app01.Book.None
res = author_obj.book_set.all()
print(res)

6.查询手机号是110的作者姓名:

author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
res = author_detail_obj.author
print(res.name)

# 如果是一个则直接拿到数据对象
            book_obj.publish
            book_obj.authors.all()
            author_obj.author_detail

# 在书写orm语句的时候跟写sql语句一样的,不要企图一次性将orm语句写完 如果比较复杂 就写一点看一点

# 基于对象 : 反向查询的时候
        当你的查询结果可以有多个的时候 就必须加_set.all()
        当你的结果只有一个的时候 不需要加_set.all()

多表查询之联表查询

联表查询---基于双下划线的跨表查询

1.查询jason的手机号和作者姓名:

res = models.Author.objects.filter(name='jason').values('author_detail__phone','name')
print(res)
# 反向
res = models.AuthorDetail.objects.filter(author__name='jason')  # 拿作者姓名是jason的作者详情
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__name')
print(res)

2.查询书籍主键为1的出版社名称和书的名称:

res = models.Book.objects.filter(pk=1).values('title','publish__name')
print(res)
# 反向
res = models.Publish.objects.filter(book__id=1).values('name','book__title')
print(res)

3.查询书籍主键为1的作者姓名:

res = models.Book.objects.filter(pk=1).values('authors__name')
print(res)
# 反向
res = models.Author.objects.filter(book__id=1).values('name')
print(res)

4.查询书籍主键是1的作者的手机号:

book author authordetail
res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
print(res)

# 你只要掌握了正反向的概念以及双下划线,那么你就可以无限制的跨表

多表查询之分组查询

select age from t group by age;
"""
    MySQL分组查询都有哪些特点
        分组之后默认只能获取到分组的依据 组内其他字段都无法直接获取了
            严格模式
                ONLY_FULL_GROUP_BY
            set global sql_mode='ONLY_FULL_GROUP_BY'
"""

# 你们的机器上如果出现分组查询报错的情况,你需要修改数据库严格模式

# 分组查询  annotate

from django.db.models import Max, Min, Sum, Count, Avg

1.统计每一本书的作者个数:

res = models.Book.objects.annotate()  # models后面点什么 就是按什么分组
res = models.Book.objects.annotate(author_num=Count('authors')).values('title','author_num')
res1 = models.Book.objects.annotate(author_num=Count('authors__id')).values('title','author_num')
print(res,res1)
"""author_num是我们自己定义的字段 用来存储统计出来的每本书对应的作者个数"""

2.统计每个出版社卖的最便宜的书的价格:

res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
print(res)

3.统计不止一个作者的图书:
        # 先按照图书分组 求每一本书对应的作者个数
        # 过滤出不止一个作者的图书

res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title','author_num')
print(res)

4.查询每个作者出的书的总价格:

res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
print(res)

# 代码没有补全 不要怕,正常写,补全给你是pycharm给你的,到后面在服务器上直接书写代码,什么补全都没有,颜色提示也没有
# 只要你的orm语句得出的结果还是一个queryset对象,那么它就可以继续无限制的点queryset对象封装的方法

F查询

F查询:能够帮助你直接获取到表中某个字段对应的数据

1.查询卖出数大于库存数的书籍:

from django.db.models import F
res = models.Book.objects.filter(maichu__gt=F('kucun'))
print(res)

2.将所有书籍的价格提升500块:
        models.Book.objects.update(price=F('price') + 500)

3.将所有书的名称后面加上爆款两个字:

from django.db.models.functions import Concat  #拼接字符串
from django.db.models import Value
models.Book.objects.update(title=Concat(F('title'), Value('爆款')))
# models.Book.objects.update(title=F('title') + '爆款')  # 所有的名称会全部变成空白
"""在操作字符类型的数据的时候 F不能够直接做到字符串的拼接"""

Q查询

1.查询卖出数大于100或者价格小于600的书籍:

res = models.Book.objects.filter(maichu__gt=100,price__lt=600)
"""filter括号内多个参数是and关系"""
from django.db.models import Q
# res = models.Book.objects.filter(Q(maichu__gt=100),Q(price__lt=600)) #Q逗号分割还是and关系
res = models.Book.objects.filter(Q(maichu__gt=100)|Q(price__lt=600))  # | or关系
# res = models.Book.objects.filter(~Q(maichu__gt=100)|Q(price__lt=600))  # ~ not关系
print(res)  # <QuerySet []>

2、Q的高阶用法  能够将查询条件的左边也变成字符串的形式

q = Q()
q.connector = 'or'
q.children.append(('maichu__gt',100))
q.children.append(('price__lt',600))
res = models.Book.objects.filter(q)  # 默认还是and关系
print(res)

 查看内部sql语句的方式

方式1:queryset对象才能够点击query查看内部的sql语句

res = models.User.objects.values_list('name','age')  
# <QuerySet [('jason', 18), ('egonPPP', 84)]>
print(res.query)

方式2:所有的sql语句都能查看

# uptade等等没有queryset对象的只需设置配置文件setting

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

今日思维导图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/173559.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

map的基础定义及运用

Map 1 使用 1 声明 /*声明map*/map<int, string> myMap {{1, "Apple"}, {2, "Banana"}, {3, "Orange"}};2 插入元素 myMap.insert(make_pair(4, "Graphes"));3 通过访问键查找和访问元素 cout << myMap[2] <<…

Ubuntu Server download

前言 Ubuntu——公共云、数据中心和边缘上最受欢迎的 Linux 发行版。自成立以来&#xff0c;Ubuntu 一直在获得市场份额&#xff0c;截至今天已接近 50%。 Ubuntu Server download VersionUbuntu Server 其它主机型号版本Ubuntu AMD历史版下载百度云Ubuntu Server all Ubuntu…

小白也能看懂的国内外 AI 芯片概述

随着越来越多的企业将人工智能应用于其产品&#xff0c;AI芯片需求快速增长&#xff0c;市场规模增长显著。因此&#xff0c;本文主要针对目前市场上的AI芯片厂商及其产品进行简要概述。 简介 AI芯片也被称为AI加速器或计算卡&#xff0c;从广义上讲只要能够运行人工智能算法…

本机idea连接虚拟机中的Hbase

相关环境&#xff1a; 虚拟机&#xff1a;Centos7 hadoop版本:3.1.3 hbase版本:2.4.11 zookeeper版本:3.5.7 Java IDE:IDEA JDK&#xff1a;8 步骤 步骤一&#xff1a;在idea创建一个maven项目 步骤二&#xff1a;在虚拟机里找到core-site.x…

【C++】map multimap

文章目录 1.map介绍2.map的使用3.multimap介绍4.multimap的使用 1.map介绍 map的文档 翻译&#xff1a; map是关联容器&#xff0c;它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。 在map中&#xff0c;键值key通常用于排序和惟一地标识元素&#x…

四川芸鹰蓬飞:抖店运营的时候注意什么?

抖店作为一个短视频平台&#xff0c;吸引了越来越多的商家加入。在抖店上进行有效的运营是提高销量和曝光度的关键。那么&#xff0c;抖店怎么设置运营呢&#xff1f;有哪些方法可以帮助商家在这个竞争激烈的平台上脱颖而出呢&#xff1f; 一、抖店怎么设置运营&#xff1f; 首…

VC++添加包含目录

安装了QT;它带有很多例子; 新建一个工程,添加一个C++源文件,随便拷个例子的源码过来; 然后VS会提示头2个include语句出错; 因为找不到这两个头文件;这需要添加包含目录; 进入项目属性页;VC++目录 - 包含目录,它之前有2个系统的值;点击右侧的下拉箭头按钮,点…

天空分割技术解决方案

图像处理技术已经成为企业提升用户体验、优化产品和服务的重要工具。美摄科技&#xff0c;作为全球领先的AI图像处理技术提供商&#xff0c;一直致力于研发和应用最先进的技术&#xff0c;以满足企业的各种需求。今天&#xff0c;我们很高兴地向大家介绍我们的新一代产品——美…

【PTA题目】L1-4 稳赢 分数 15

L1-4 稳赢 分数 15 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 大家应该都会玩“锤子剪刀布”的游戏&#xff1a;两人同时给出手势&#xff0c;胜负规则如图所示&#xff1a; 现要求你编写一个稳赢不输的程序&#xff0c;根据对方的出招&#xff0c;给出对应的赢招。但…

AR远程辅助技术应用到气象部门有何好处?

随着科技的不断发展&#xff0c;人类对于自然环境的理解和掌控能力也在不断提升。其中&#xff0c;AR(增强现实)技术的应用&#xff0c;为气象监控带来了革命性的变化。AR气象远程监控&#xff0c;就是将AR技术与气象监控相结合&#xff0c;通过虚拟与现实的融合&#xff0c;实…

数字化转型导师坚鹏:数字化时代银行网点厅堂营销5大痛点分析

数字化时代银行网点厅堂营销存在以下5大痛点&#xff1a; 1、业务办理时间较长。目前很多银行业务办理时间仍然较长&#xff0c;可能的原因包括银行业务办理流程比较复杂、柜员操作技能不够熟练、银行系统的稳定性欠佳、网点某段时间客户比较多等。 2、现场提交材料太多。银行…

事件溯源(Event Sourcing)和命令查询责任分离(CQRS)经验

这篇文章是实现一个基于 CQRS 和事件溯源原则的应用程序&#xff0c;描述这个过程的方式&#xff0c;我相信分享我面临的挑战和问题可能对一些人有用。特别是如果你正在开始自己的旅程。 业务背景 项目的背景与空中交通管理&#xff08;ATM&#xff09;领域相关。我们为一个 …

Spring框架学习 -- 核心思想

目录 (1) Spring是什么? (2) 什么是IOC容器? (3) 从传统开发认识spring (4) 这种传统开发的缺陷 (5)解决传统开发中的缺陷 (6) 对比总结规律 (7) 理解IOC 创作不易多多支持 (1) Spring是什么? 我们常说的Spring的全称是: Spring Framework(Spring框架), 它是一个开源…

ueditor整合到thinkPHP里

<?phpnamespace app\ueditor\controller;use think\Controller;class Ueditor extends Controller {//首页public function upload(){//header(Access-Control-Allow-Origin: http://www.baidu.com); //设置http://www.baidu.com允许跨域访问//header(Access-Control-Allow…

基于人工大猩猩部队算法优化概率神经网络PNN的分类预测 - 附代码

基于人工大猩猩部队算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于人工大猩猩部队算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于人工大猩猩部队优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&a…

Linux操作系统使用及C高级编程-D11-D13结构体

由一批数据组合而成的结构型数据。组成结构型数据的每个数据称为结构型数据的“成员”&#xff0c;其描述了一块内存空间的大小及解释意义。 语法&#xff1a; struct 结构体名 { 结构体成员列表 }; 下图是struct的定义和使用方法&#xff0c;其中20行这种赋值方式错误&#xf…

c语言上机作业:迭代法求平方根

1.题目 设计一个函数func用迭代法编程求一个数的平方根。平方根的迭代公式为&#xff1a;牛顿迭代法&#xff0c;(要求前后两次迭代值求差的绝对值小于10的-9次方) 2.思路 a.这里要求我们设置一个函数能够完成牛顿迭代法&#xff0c;这里需要使用到函数迭代的知识&#xff0…

时间复杂度与空间复杂度

我们知道算法的效率分为时间效率和空间效率&#xff0c;接下来我们就对这两者进行讨论。 一.时间复杂度. 又被称为时间效率&#xff0c;主要反映一个算法的运行速度。 定义&#xff1a;计算机算法中&#xff0c;算法的时间复杂度是一个函数&#xff0c;它定量描述了该算法的…

excel自定义函数之汉字转为拼音及大写字母

使用场景&#xff1a;想把姓名转化为拼音格式&#xff0c;然后拼音转为大写字母 至于怎么在excel里面自定义函数&#xff0c;自行百度都有&#xff0c;这里简单截图看看。 步骤&#xff1a;文件》选项》自定义功能区》 打开编辑窗口 把下面这段代码粘贴就能实现汉字转化为拼音…

Vulnhub 解决虚拟机网络问题

前言&#xff1a; 有的时候&#xff0c;我们从vulnhub官网下载ovf文件导入到虚拟机后&#xff0c;使用扫描器扫描存活的时候发现扫不到靶机的IP&#xff0c;这是因为虚拟机的网卡配置有问题。我们需要进安全模式修改一些配置。 1. 在虚拟机开机的时候按一下上下键&#xff0c;让…