Django模型层

模型层

与数据库相关的,用于定义数据模型和数据库表结构。 在Django应用程序中,模型层是数据库和应用程序之间的接口,它负责处理所有与数据库相关的操作,例如创建、读取、更新和删除记录。Django的模型层还提供了一些高级功能

首先准备工作:切换mysql数据库

DATABASES = {'default': {# 'ENGINE': 'django.db.backends.sqlite3','ENGINE': 'django.db.backends.mysql','NAME': 'db2','USER': 'root','PASSWORD': '12345','HOST': '127.0.0.1','PORT': 3306,'CHARSET': 'utf8'}

测试脚本

接下来我们可以使用测试脚本来直接运行,注意后面的Django代码必须写在测试脚本下面

把测试脚本放进一个py文件即可
import os
import sys
import django
if __name__ == "__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE", "项目名称.settings")import djangodjango.setup()django.setup()from app01 import models

常用的关键字

create描述
filter创建数据并直接获取当前创建的数据对象
first/last根据条件筛选数据 结果是QuerySet [数据对象1,数据对象2]
update拿queryset里面第一个元素/拿queryset里面最后一个元素
delete删除数据(批量删除)
all查询所有数据 结果是QuerySet [数据对象1,数据对象2]
values根据指定字段获取数据 结果是QuerySet [{}},{},{},{}]
values_list根据指定字段获取数据 结果是QuerySet [(),(),(),()]
distinct去重 数据一定要一模一样才可以 如果有主键肯定不行
order_by根据指定条件排序 默认是升序 字段前面加负号就是降序
get根据条件筛选数据并直接获取到数据对象 一旦条件不存在会直接报错 不建议使用
exclude取反操作
reverse颠倒顺序(被操作的对象必须是已经排过序的才可以)
count统计结果集中数据的个数
exists

判断结果集中是否含有数据 如果有则返回True 没有则返回False

示例

如果使用get,建议加上try

if __name__ == "__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoProject.settings")import djangodjango.setup()from app01 import modelstry:res = models.Userinfo.objects.filter(pk=1).get()except Exception as f:print(f)

value与value_list

res = models.Userinfo.objects.values('id', 'username', 'password')for i in res:print(i.get('id'))    # <QuerySet [{'id': 1, 'username': 'kk', 'password': '1234'}, {'id': 2, 'username': 'cc', 'password': '232'}, {'id': 3, 'username': 'rer', 'password': '323'}]># 1 2 3 索引0为id,1为usernameprint(res)   # <QuerySet [(1, 'kk', '1234'), (2, 'cc', '232'), (3, 'rer', '323')]>

查看内部sql语句

只有返回的结果是queryset对时才能用query查看

res = models.Userinfo.objects.values('id', 'username', 'password')for i in res:print(i.get('id')) print(res.query)"""SELECT `app01_userinfo`.`id`, `app01_userinfo`.`username`, `app01_userinfo`.`password` FROM `app01_userinfo`"""

distinct 去重

 res = models.Userinfo.objects.all().values('password').distinct()print(res)

order_by 排序

    res1 = models.Userinfo.objects.all().order_by('username')    # <QuerySet [<Userinfo: Userinfo object (2)>, <Userinfo: Userinfo object (1)>, <Userinfo: Userinfo object (3)>]print(res1)
"""默认升序"""

基于双下划线的查询

查询年龄大于xx

"""查看年龄大于或小于32的数据"""res = models.Userinfo.objects.filter(age__gt=32)\(age__lt=32)print(res)"""查看大于等于或小于等于32的数据"""res = models.Userinfo.objects.filter(age__gte=32)\(age__lte=32)print(res)"""查看18-32之间的数据,收尾都要"""res = models.Userinfo.objects.filter(age__range=[18, 32])print(res)"""查看带s字段的数据"""res = models.Userinfo.objects.filter(username__contains='s')print(res) # <QuerySet [<Userinfo: Userinfo object (2)>]>"""姓名以c开头或结尾startwith\endwith"""res = models.Userinfo.objects.filter(username__startswith='c')print(res)"""查看注册时间两个参数auto_now = false 当我们更新数据时,只要更新就会更新时间auto_add = False 当auto_add=True时,添加数据时会自动添加当前时间"""register_time = models.DateTimeField(auto_now=True, auto_now_add=True)

多表查询(跨表查询)

 orm外键字段的创建

和mysql外键关系一样的判断规律

1.一对多  外键字段建在多的一方2.多对多  外键字段统一建在第三张关系表3.一对一  建在任何一方都可以,但是建议建在查询频率较高的表中注意:目前关系的判断可以采用表与表之间换位思考原则

基础表的准备

  1. 创建基础表(书籍表、出版社表、作者表、作者详情)

  2. 确定外键关系

  3. orm的创建

    一对一  ORM与MySQL一致 外键字段建在查询较高的一方 一对多  ORM与MySQL一致 外键建在多的一方多对多  ORM比MySQL有更多的变化1.外键字段可以直接建在某张表中(查询频率较高的)内部会自动帮你创建第三张关系表2.自己创建第三张关系表并创建外键字段

4.​ 针对一对多和一对一同步到表中之后自动_id的后缀,如book中的外键字段publish,会自动变成publish_id。

建表

class Book(models.Model):name = models.CharField(max_length=32)   # 书名price = models.DecimalField(max_digits=8, decimal_places=2)    # 价格publish_date = models.DateField(auto_now_add=True)  # 出版日期maichu = models.IntegerField(2000)    # 卖出数量kucun = models.IntegerField(3000)    # 库存"""建立外键"""# 一对多publish = models.ForeignKey(to='Publish', on_delete=True)   # publish不需要加_id,当为外键时自动会加# 多对多authors = models.ManyToManyField(to='Author')class Publish(models.Model):name = models.CharField(max_length=32)   # 出版社名称addr = models.CharField(max_length=32)   # 出版社def __str__(self):return self.nameclass Author(models.Model):   #作者表name = models.CharField(max_length=32)age = models.IntegerField()# 一对一author_list = models.OneToOneField(to='AuthorList', on_delete=True)class AuthorList(models.Model):   # 作者详情表phone = models.CharField(max_length=32)addr = models.CharField(max_length=32)

注意事项

1.创建一对多关系和sql语句一样,外键建立到多的那张表上,不同的是,我们可以不讲究关联表和被关联表的建立顺序。字段类为ForeignKey在django2.x版本以上,建立一对多关系时需要指定on_delete参数为CASCADE,不加会报错,不过也不一定就是CASCADE,可能为其他实参,这里不展开。建立外键时,系统会自动加上_id后缀作为字段名。2.创建多对多关系sql中是将两张表建立好后,将外键字段创建在第三张表中,而django为我们省去了这一步骤,我们可以在多对多关系双方的一个模型表中直接建立一个虚拟外键,ManyToManyField在底层,sql依旧创建了第三张表来存储两表的多对多关系,但是在orm操作中我们就可以将模型表中的外键当做实实在在的联系,因为在查询时,我们感受不到第三张的表的存在。多对多关系的外键没有on_delete关键字参数。3.创建一对多关系一对一的字段类为OneToOneField,建议建立在查询频率高的一方。建立一对一关系时需要指定on_delete参数,否则报错。

一对多的外键增删改查

增加

models.Book.objects.create(name='三味书屋', price=1500, publish_date='2022-1-1', maichu=3500, kucun=2000, publish_id=1)"""第二种方式通过对象来添加"""publish_obj = models.Publish.objects.filter(pk=1).first()models.Book.objects.create(name='三味书屋', price=1500, publish_date='2022-1-1', maichu=3500, kucun=2000,publish=publish_obj)

删除

    """删除"""models.Publish.objects.filter(pk=1).delete()    # 级联删除时,会删除出版社里所有的书籍,所以不建议这样删除models.Book.objects.filter(pk=1).delete()       # 只删除图书即可

修改

    """修改"""models.Book.objects.filter(pk=1).update(publish_id=3)"""第二种方式"""publish_obj = models.Publish.objects.filter(pk=1).first()models.Book.objects.filter(pk=1).update(publish_id=publish_obj)
多对多的外键增删改查

增加(add)

book_obj = models.Book.objects.filter(pk=3).first()
print(book_obj.authors)   # 打印结果为dj5.Author.None,说明已经跳转到第三张表了
book_obj.authors.add(1)使用对象添加book_obj=models.Book.objects.filter(pk=2).first()authors_obj = models.Author.objects.filter(pk=3).filter()
authors_obj1 = models.Author.objects.filter(pk=4).filter()
book_obj.authors.add(authors_obj,authors_obj1)

修改(set)

修改作者

"""修改"""
book_obj.authors.set([2, 4])    # 将d为2的书籍绑定给主键为2,4的作者
"""使用对象修改"""book_obj.authors.set(authors_obj)

删除(remove)

"""删除"""
book_obj.authors.remove(1,2,3)    # 删除主键id为1,2,3的书籍"""使用对象删除"""
book_obj.authors.remove(authors_obj)

清空(creal)

清空i书籍id为1 的所有作者

使用clear(清空)直接清理即可

book_obj.authors.clear()
直接清空所有id
查询之正反向

正向:外键字段在我这边,那么我查询你就是正向

反向:外键字段不在我这边,那么我查询你就是反向

图书与出版社比较,图书为多,出版社为一,那么外键字段就在我这边,使用图书查询出版社就是正向查询

        book------>外键字段再我这(正向查询)-------->publish,按(外键)字段

        publish----->外键字段不在我这(反向查询)------>book,按表名小写

或加上_set 

出版社查询图书,出版社为一,图书为多,那么外接字段就不在我这边,使用出版社查询图书就是反向查询

子查询例题

查询书籍主键为3的出版社

res = models.Book.objects.filter(pk=3).first()
"""1.首先筛选出id=3的书籍2.判断正反向:图书差出版社,一对多为正向3.直接打印出结果,如果需要地址则可以使用。addr"""print(res.publish)
print(res.publish.addr)

查询书籍主键为3的作者

# 查询书籍主键为3的作者
res = models.Book.objects.filter(pk=3).first()
print(res.authors.all())

 查询作者鲁迅的电话号码


# 3.查询作者鲁迅的电话号码
res = models.Author.objects.filter(name='鲁迅').first()
print(res.author_list.phone)

查询出版社是浓浓出版社出版的书

查询出版社是东方出版社出版的书
publish_obj = models.Publish.objects.filter(name='浓浓出版社').first()
res = publish_obj.book_set
print(res.all())# <QuerySet [<Book: Book object (3)>, <Book: Book object (4)>]>

查询作者是鲁迅写过的书

publish_obj = models.Author.objects.filter(name='鲁迅').first()
res = publish_obj.book_set.all()
print(res)

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

查询手机号是110的作者姓名
publish_obj = models.AuthorList.objects.filter(phone=110).first()
res = publish_obj.author
print(res.name)

联表查询

基于双下划线的查询

1.查询鲁迅的手机号和作者姓名

res = models.Author.objects.filter(name='鲁迅').values('author_list__phone', 'name')
print(res)

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

查询书籍主键为3的出版社名称和书的名称
res = models.Book.objects.filter(pk=3).values('publish__name', 'name')
print(res)    # <QuerySet [{'publish__name': '浓浓出版社', 'name': '三味书屋'}]>

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

查询书籍主键为3的作者姓名
res = models.Book.objects.filter(pk=3).values('authors__name')
print(res)

查询书籍主键为3的作者手机号

查询书籍主键是3的作者的手机号
res = models.Book.objects.filter(pk=3).values('authors__author_list__phone')
print(res)

聚合查询

通常聚合都是通过分组使用,只要和数据库相关的模块基本都在Django.db.models里,如果没有可能在Django.db中

在orm中,聚合函数的关键字:aggregate

from django.db.models import Avg, Sum, Max, Min, Count
res = models.Book.objects.aggregate()

查询所有书籍的金额

sql语句:
select avg(price)from bookorm语句:from django.db.models import Avg, Sum, Max, Min, Count
res = models.Book.objects.aggregate(agv_price=Avg('price'), sum_price=Sum('price'))

分组查询

严格模式:ONLY_FULL_GROUP_BY

        set global sql_mode='ONLY_FULL_GROUP_BY'

案例:

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

# 统计每个书的作者
res = models.Book.objects.annotate(authors_num=Count('authors')).values('name', 'authors__name')
print(res)

事物

事物是mysql数据库中一个重要的概念,

目的:是为了保证多sql语句执行成功,或执行失败,前后保持一致,保证数据安全

开启事物

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习Python实战】logistic回归

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;机器学习python实战 欢迎订阅&#xff01;后面的内容会越来越有意思~ ⭐内容说明&#xff1a;本专栏主要针对机器学习专栏的基础内容进行python的实现&#xff0c;部分…

PlantUML基础使用教程

环境搭建 IDEA插件下载 打开IEDA系列IDE&#xff0c;从FIle–>Settings–>Plugins–>Marketplace 进入到插件下载界面&#xff0c;搜索PlantUML&#xff0c;安装PlantUML Integration和PlantUML Parser两个插件&#xff0c;并重启IDE 安装和配置Graphviz 进入官网…

《视觉SLAM十四讲》-- 后端 2

文章目录 09 后端 29.1 滑动窗口滤波和优化9.1.1 实际环境下的 BA 结构9.1.2 滑动窗口法 9.2 位姿图9.2.1 位姿图的意义9.2.2 位姿图优化 09 后端 2 9.1 滑动窗口滤波和优化 9.1.1 实际环境下的 BA 结构 由于计算机算力的限制&#xff0c;我们必须控制 BA 的规模&#xff0c…

进程程序替换与exec系统调用

进程程序替换 进程程序替换是指将一个正在运行的进程替换为另一个可执行程序。它的本质是调用了Linux操作系统中的exec系统调用。而exec系统调用是一个家族函数&#xff0c;例如execl、execv、execle、execve等。它们的共同特点是当当前进程执行到该函数时&#xff0c;就会直接…

Bert浅谈

优点 首先&#xff0c;bert的创新点在于利用了双向transformer&#xff0c;这就跟openai的gpt有区别&#xff0c;gpt是采用单向的transformer&#xff0c;而作者认为双向transformer更能够融合上下文的信息。这里双向和单向的区别在于&#xff0c;单向只跟当前位置之前的tocke…

Nginx安装配置与SSL证书安装部署

一、Nginx Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;被广泛用于构建现代化的Web应用和提供静态内容。 nginx官网 这里下载nginx-1.24.0-zip Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;被广泛用于构建现代化的Web应用和提供静态内…

测试开发环境下centos7.9下安装docker的minio

按照以下方法进行 1、安装docker&#xff0c;要是生产等还是要安装docker-ce yum install docker 2、启动docker service docker start 3、 查看docker信息 docker info 4、加到启动里 systemctl enable docker.service 5、开始docker pull minio/minio 但报错&#x…

【机器学习7】优化算法

1 有监督学习的损失函数 1.1 分类问题 对二分类问题&#xff0c; Y{1,−1}&#xff0c; 我们希望sign f(xi,θ)yi&#xff0c; 最自然的损失函数是0-1损失&#xff0c; 函数定义特点0-1损失函数非凸、非光滑&#xff0c;很难直接对该函数进行优化Hinge损失函数当fy≥1时&…

汽车以太网IOP测试新利器

IOP测试目的 汽车以太网物理层IOP&#xff08;Interoperability &#xff09;测试&#xff0c;即测试被测对象以太网物理层之间的互操作性。用于验证车载以太网PHY能否在有限时间内建立稳定的链路&#xff1b;此外&#xff0c;还用于验证车载以太网PHY可靠性相关的诊断特性&am…

Linux环境下C++ 接入OpenSSL

接上一篇&#xff1a;Windows环境下C 安装OpenSSL库 源码编译及使用&#xff08;VS2019&#xff09;_vs2019安装openssl_肥宝Fable的博客-CSDN博客 解决完本地windows环境&#xff0c;想赶紧在外网环境看看是否也正常。毕竟现在只是HelloWorld级别的&#xff0c;等东西多了&am…

浅谈智能安全配电装置应用在银行配电系统中

【摘要】银行是国家重点安全保护部分&#xff0c;关系到社会资金的稳定&#xff0c;也是消防重点单位。消防安全是银行工作的重要组成部分。在银行配电系统中应用智能安全配电装置&#xff0c;可以提高银行的智能控制水平&#xff0c;有效预防电气火灾。 【关键词】银行&#…

如何快速下载mysql的不同版本并启动mysql服务?

如何快速下载mysql的不同版本并启动mysql服务&#xff1f; 下载mysql的安装版本 首先我们要使用到迅雷去下载&#xff0c;因为迅雷下载是很快的。在迅雷里面搜索下面的Mysql Installer安装窗口&#xff0c;如下图&#xff1a; 连接&#xff1a;https://dev.mysql.com/downlo…

fopen/fwrite/fread 对UNICODE字符写入的总结

windows对fopen函数进行了升级&#xff0c;可以支持指定文件的编码格式&#xff08;ccs参数指定&#xff09;。 例如&#xff1a; FILE *fp fopen("newfile.txt", "rt, ccsUTF-8"); 当以 ccs 模式打开文件时&#xff0c;进行读写操作的数据应为 UTF-16…

Selenium自动化测试框架

一.Selenium概述 1.1 什么是框架? 框架&#xff08;framework&#xff09;是一个框子——指其约束性&#xff0c;也是一个架子——指其支撑性。是一个基本概念上的 结构用于去解决或者处理复杂的问题。 框架是整个或部分系统的可重用设计&#xff0c;表现为一组抽象构件及…

【Machine Learning in R - Next Generation • mlr3】

本篇主要介绍mlr3包的基本使用。 一个简单的机器学习流程在mlr3中可被分解为以下几个部分&#xff1a; 创建任务 比如回归、分裂、生存分析、降维、密度任务等等挑选学习器&#xff08;算法/模型&#xff09; 比如随机森林、决策树、SVM、KNN等等训练和预测 创建任务 本次示…

C语言每日一题(32)环形链表

力扣网 141.环形链表 题目描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾…

LLM大模型4位量化实战【GPTQ】

权重量化方面的最新进展使我们能够在消费类硬件上运行大量大型语言模型&#xff0c;例如 RTX 3090 GPU 上的 LLaMA-30B 模型。 这要归功于性能下降最小的新型 4 位量化技术&#xff0c;例如 GPTQ、GGML 和 NF4。 在上一篇文章中&#xff0c;我们介绍了简单的 8 位量化技术和出…

GZ038 物联网应用开发赛题第10套

2023年全国职业院校技能大赛 高职组 物联网应用开发 任 务 书 &#xff08;第10套卷&#xff09; 工位号&#xff1a;______________ 第一部分 竞赛须知 一、竞赛要求 1、正确使用工具&#xff0c;操作安全规范&#xff1b; 2、竞赛过程中如有异议&#xff0c;可向现场考…

Spring学习③__Bean管理

目录 IOC接口ApplicationContext 详解IOC操作Bean管理基于xml方式基于xml方式创建对象基于xml方式注入属性使用set方法进行注入通过有参数的构造进行注入p 名称空间注入&#xff08;了解&#xff09; 基于xml方式注入其他类型属性xml 注入数组类型属性 IOC接口 IOC思想基于IOC…

Linux 无名管道实现文件复制

无名管道 通过一个管道&#xff08;假象&#xff09;进行传输数据&#xff0c;但是这个管道的传输方式是单工&#xff08;半双工&#xff09;的&#xff0c;就是这个管道允许进行发送和接受数据&#xff0c;不过不能同时进行。 创建无名管道 这里用到一个pipe&#xff08;&…