Django ORM 多表操作:一对一、一对多、多对多的增删改,基于对象/双下划线的跨表查询

news2025/7/27 20:31:07

Django model ORM数据表相关操作

分析思路,创建数据表

对于表操作,表之间的关联关系,必须理解他们之间的关系,对于编程很重要。可以看看映射关系、外键和relationship查询 ,至少明白外键相关基本知识。

(一)多表查询
    一对一:models.OneToOneField(to_field='id',to='Authordatil')
    一对多:(外键设置唯一性)
        models.ForeignKey(to='Publish',to_field='id')

    多对多:自动生成第三张表
        models.ManyToManyField(to='Author')


(二)创建表模型
     作者与详情  ( 一对一 )
     书与作者( 多对多 )
     出版社与书(一对多 )

     出版社:id name  add  email
     书: id  name  price  publish

     作者: id  name  sex  authordatil
     详情: id  photo  address

models.py 文件,创建数据模型

class Publish(models.Model):
    name = models.CharField(max_length=100)
    address = models.CharField(max_length=64)
    email = models.EmailField()

    def __str__(self):
        return '%s,%s,%s' % (self.name, self.address, self.email)


class Author(models.Model):
    name = models.CharField(max_length=32)
    choices = ((0, '女'), (1, '男'))
    sex = models.SmallIntegerField(choices, default=0)  # 数字整型
    # 作者与详情:(一对一)   to='AuthorDetail'  加引号,这个表能找到就可以,不用引号,类必须在上面定义
    authordatil = models.OneToOneField(to_field='id', to='Authordatil', on_delete=models.CASCADE)

    def __str__(self):
        return self.name


class Authordatil(models.Model):
    photo = models.CharField(max_length=124)
    address = models.CharField(max_length=64)


class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    # 出版社与书(一对多关系)外检设置唯一性,关联的表,关联的字段
    publish = models.ForeignKey(to='Publish', to_field='id', on_delete=models.CASCADE)
    # 书与作者关系是多对多关系
    authors = models.ManyToManyField(to='Author')
  • 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
  • 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。

一.添加/删除/修改表记录

1.1一对多添加记录

一对多添加记录需要先添加父表(Publish)记录,再添加子表(Book)记录,反过来则会报错
简单测试,直接添加Book,views中定义一个方法:

def add_book(request):
    Book.objects.create(name='红楼梦', price=20.0, publish_id=1)
    return HttpResponse('成功插入一条Book记录!')

看看控制台,会报错了
在这里插入图片描述
'django.db.utils.IntegrityError: FOREIGN KEY constraint failed初步判定主键约束错误,也就是说publish_id 对应的Publish不存在。那就先添加几个Publish吧

这里有数据库建表的相关文章,不明白的同学可以看看:https://blog.csdn.net/qq_43030934/article/details/127495951?spm=1001.2014.3001.5501

1.1.1 views中定义一个方法:

def add_publish(request):
    Publish.objects.create(name='北京出版社', address='北京', email='itjavawfc@163.com')
    Publish.objects.create(name='安徽出版社', address='安徽', email='itjavawfc@163.com')
    Publish.objects.create(name='人教版出版社', address='北京', email='itjavawfc@163.com')
    li=[]
    for i in range(5):
        li.append(Publish(name='新华出版社%s' % i, address='北京', email='itjavawfc@163.com'))  # 批量生成对象
    Publish.objects.bulk_create(li)
    return HttpResponse('成功插入Publish记录!')

在这里插入图片描述
查看数据库信息:
在这里插入图片描述

1.1.2 出版社Publish数据有了,现在继续测试添加Book功能了

def add_book(request):
    Book.objects.create(name='红楼梦', price=20.0, publish_id=1)
    return HttpResponse('成功插入一条Book记录!')

在这里插入图片描述
查看数据库数据,可以看到数据已经成功插入了。
在这里插入图片描述
简单理解刚才的问题: 主键约束了之后,插入book前提是已经有了外键的数据,publish_id,也就是有一个Publish记录,这样才可以插入Book记录,且publish_id正好是Publish记录中对应的一条记录。

通过对象添加记录
首先得到一个publish对象,然后作为参数直接插入到Book表中,看看数据库信息。

def add_book_by_publish(request):
    publish = Publish.objects.filter(pk=1).first()
    Book.objects.create(name='红楼梦', price=34.5, publish=publish)
    return HttpResponse('通过对象插入一条记录!')

在这里插入图片描述pk 表示主键,一旦主键改变,还是会找到对应的主键来获取对象,如果通过主键查询道德数据为null,那么表示不存在这个记录,也就无法正常插入Book了。

2. 一对多删除记录

  • 删除数据时,先删除子表(bokk)记录,再删除父表(publish)记录;否则是会报错的。这里就不演示了。

下面是直接删除book数据的接口函数

def del_book(request):
    Book.objects.filter(name='红楼梦').first().delete()
    return HttpResponse('删除记录!')

3.一对多修改记录

  • 通过queryset对象的update方法修改
  • 通过对象的属性修改,调用对象的save()方法保存
  • 通过queryset对象的update方法修改

方式一:通过 _id 修改

def up_date_book(request):
    Book.objects.filter(pk=2).update(name='西游记', publish_id=1)
    return HttpResponse('通过ID修改!')

方式二:通过 对象修改修改

def up_date_book_by_publish(request):
    publish = Publish.objects.filter(pk=1).first()
    Book.objects.filter(pk=2).update(name='东游记', price=100.0, publish=publish)
    return HttpResponse('通过对象修改!')

3.1通过对象的属性修改,调用对象的save()方法保存

方式一:通过 _id 修改

def up_date_book_by_id_book(request):
    book = Book.objects.filter(pk=4).first()
    book.publish_id = 104
    book.price = 200.0
    book.save()
    return HttpResponse('upDateBookByIDBook!')

方式二:通过对象修改

def up_date_book_by_book(request):
    book = models.Book.objects.filter(pk=4).first()
    publish = models.Publish.objects.filter(pk=105).first()
    book.publish = publish
    book.save()
    return HttpResponse('upDateBookBook!')

4.多对多增删改记录

先准备测试用的数据

def add_author_detail(request):
    Authordatil.objects.create(photo='www.baidu.com/author1.png', address='天上人间1包间')
    Authordatil.objects.create(photo='www.baidu.com/author2.png', address='天上人间2包间')
    Authordatil.objects.create(photo='www.baidu.com/author3.png', address='天上人间3包间')
    Authordatil.objects.create(photo='www.baidu.com/author4.png', address='天上人间4包间')
    return HttpResponse('添加AuthorDetail')

def add_author(request):
    Author.objects.create(name='tom', sex=0,authordatil_id=1)
    Author.objects.create(name='tony', sex=1,authordatil_id=2)
    Author.objects.create(name='jack', sex=1,authordatil_id=3)
    Author.objects.create(name='ant', sex=0,authordatil_id=4)
    return HttpResponse('添加addAuthor')

4.1多对多增加记录

(1)通过对象添加记录

多对多

  • 添加数据时,先添加父表记录(book,author),再添加子表(book_author_relation)记录
  • 删除数据时,先删除子表记录(book_author_relation),再删除父表记录(book,author)

现在就要为这边《东游记》这本书添加作者

def add_author_by_book(request):
    tom = Author.objects.filter(name='tom').first()
    book = Book.objects.filter(name='东游记').first()
    tony = Author.objects.filter(name='tony').first()
    jack = Author.objects.filter(name='jack').first()
    book.authors.add(tom)
    # 一次添加两个作者,中间用逗号隔开
    book.authors.add(tony, jack)
    return HttpResponse('给书添加作者')

看数据库数据表: books_book_authors
在这里插入图片描述

(2)通过 id 添加记录

直接上代码

多对多删除记录

多对多清空记录

多对多修改记录

多对多增加记录

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

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

相关文章

App Languages 批量导入管理Android多语言文案

AppLanguages支持安卓的多语言文案管理啦,支持批量的检测,批量导入,批量删除,批量替换,批量导出。 操作界面 批量导入 1)需要选择res文件夹的路径,方便创建和寻找本地的多语言文件 2&#xff…

ui界面的介绍

创建一个项目时默认选择带有ui界面,ui界面的作用是方便设计者设计功能。 ui界面常见的功能: 方便对象的创建,拖入到窗口中即可方便布局,可以直接使用布局对控件进行修饰方便制作信号,通过转到槽的机制,快速…

Cesium 入门(一)无服务 Cesium 环境

Cesium 入门(一)无服务环境 一、无服务环境下的 Cesium 无网络环境下的静态 cesium 地图服务,cesium 1.98.1 已经支持无 token 情况下的地图显示,默认 token 可用来展示 3d 地图,老版本 cesium,需自行前往…

Golang入门笔记(15)—— 数组

编程的世界中,或许是因为一次一次的定义变量,维护管理起来都太费劲了,所以推出了数组,将数据用数组的形式管理起来。 参考代码: package mainimport "fmt"func main() {var scores [5]intscores[0] 90sco…

RabbitMQ基础

文章目录一. Hello World二. Work Queues三. 消息应答1. 自动应答2. 手动应答3. 批量应答4. 消息自动重新入队四. 持久化1. 实现队列持久化2. 实现消息持久化五. 消息不公平分发1. 配置不公平分发2. 预取值六. 发布确认1. 发布确认原理2. 开启发布确认3. 单个发布确认4. 批量发…

DOM介绍及DOM获取元素的方式

1、DOM介绍 DOM(Document Object Model):文档对象模型其实就是操作html中的标签的一些能力我们可以操作哪些内容○ 获取一个元素 ○ 移除一个元素 ○ 创建一个元素 ○ 向页面里面添加一个元素 ○ 给元素绑定一些事件 ○ 获取元素的属性 ○ …

Hive集群部署实验

目录一、实验介绍1.1 实验内容1.2 实验知识点1.3 实验环境1.4 实验资源1.5 实验步骤清单二、实训架构三、实验环境准备四、实验步骤4.1 Hive部署4.1.1 安装Hive4.1.3 修改hive配置文件4.1.4 创建Hadoop测试目录4.1.5 初始化hive元数据库4.2 Hive测试4.2.1 启动Hive4.2.2 创建测…

pytorch的gpu版本安装以及cpu版本的卸载

目录 前言 一、安装显卡驱动 二、安装Visual Studio 2019 三、安装CUDA 四、安装cudnn 五、安装anaconda 六、安装PyTorch 前言 因为最近需要导师的指导,我开始了unet的学习,虽然之前也学习过机器学习,但是只是浅尝辄止,没…

你好,以太坊社区,你准备好参加 ETH India 2022 黑客马拉松活动了吗

你好,以太坊社区,我们很高兴通过 ETH Global即将举行的ETH India 2022 黑客马拉松活动将Cartesi 技术带到亚洲!如果你是一位喜欢探索尖端技术且是一位创新型开发人员,我们期待着你的到来,并且想帮助你将美好的DApps 发…

[BLIP]-多模态Language-Image预训练模型

论文:https://arxiv.org/pdf/2201.12086.pdf 代码:GitHub - salesforce/BLIP: PyTorch code for BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation demo:BLIP - a Hugging Face …

代码随想录算法训练营第二天|LeetCode 977.有序数组的平方 、209.长度最小的子数组 、59.螺旋矩阵II

LeetCode 977.有序数组的平方 题目链接&#xff1a;977.有序数组的平方 思路&#xff1a; 1、先对每个数进行遍历平方&#xff0c;并插入新的容器中 2、对容器进行排序&#xff0c;返回就可以了 缺陷&#xff1a;开辟了新的容器空间 class Solution { public:vector<int…

2019年1+X 证书 Web 前端开发中级理论考试题目原题+答案——第二套

&#x1f4da;文章目录 &#x1f3af;关于1X标准 &#x1f3af;关于中级考点 ⏩&#x1f4bb;答案速查 一、单选题&#xff08;每小题2分&#xff0c;共30小题&#xff0c;共60分&#xff09; 二、多选题&#xff08;每小题2分&#xff0c;共15小题&#xff0c;共30分&…

测试工程师必备的数据库知识

测试工程师必备的数据库知识 1. 数据库的重要性 数据库是一个容器&#xff0c;仓库存的是货物&#xff0c;而数据库存的是数据。数据很好的解决了数据到哪里去&#xff0c;以及数据从哪里来的问题。 2. 数据库工具的选择 选择数据库是根据项目特点&#xff0c;架构&#xff0c;…

枚举类与注解(复习)

枚举类的使用 枚举类的使用如何自定义枚举类枚举类中的方法注解 Annotation自定义注解jdk 中四个元注解RetentionTargetDocumentedInheritedJdk 8 中注解新特性可重复注解 Repeatable类型注解类的对象只有有限个&#xff0c;确定的 星期&#xff1a;Monday(星期一)、…、Sunday…

为什么学3D建模前没人告诉我这些,常见问题答疑

1️⃣入门前建模新手要做好哪些准备❓ 一开始啥都不懂先别着急学&#xff0c;先刷刷Pinterest&#xff0c;ArtStation等业内比较知名的网站&#xff0c;多看优秀作品提高审美水平&#xff0c;这样能快速了解建模行业&#xff0c;到时上手操作也不至于脑袋空空没有想法&#xf…

C语言-数据类型

C语言-数据类型0. 概念表达式与语句字面量常量表达式/表达式1. 整型有符号/无符号进制数原码/补码/反码int/charfloat/double2. 字符型字符型与整型字符与进制数/字符型进制数putchar/getchar转义字符字符集与字符编码C语言字符串型puts/getsprintfscanf3. 数据运算/IO基本运算…

计算机SSM毕设项目 软件工程毕业设计【源码+论文】

文章目录前言 题目1 : 基于SSM的游戏攻略资讯补丁售卖商城 <br /> 题目2 : 基于SSM的疫情期间医院门诊网站 <br /> 题目3 : 基于SSM的在线课堂学习设计与实现<br /> 题目4 : 基于SSM的大学生兼职信息系统 <br /> 题目5 : 基于SSM的大学生社团管理系统 …

nginx降权+匹配php

目录 nginx降权启动 确认普通用户无法开启nginx 创建普通用户&#xff1a; 测试是否可以启动nginx: 创建必须的相关文件 使用root用户copy配置文件中网页支持类型文件 使用root用户拷贝nginx配置文件 设置权限 修改配置文件 安装 PHP 7.4&#xff0c;配合 Nginx 安装 P…

wireshark提取视频数据之RTP包中提取H264和H265

wireshark提取视频数据之RTP包中提取H264和H265 文章目录wireshark提取视频数据之RTP包中提取H264和H2651 背景2 提取前工作3 H264视频从RTP包中提取步骤4 H265视频从RTP包中提取步骤5 后记1 背景 在流媒体相关问题分析时&#xff0c;抓包分析是非常重要的手段&#xff0c;比如…

容器入门:一文了解容器的发展历史、技术和术语

学习目标 本文为Amazon容器入门课程笔记&#xff0c;内容是容器化背后的发展历史和概念&#xff0c;介绍容器生态系统中使用的特定技术&#xff0c;并讨论容器在微服务架构中的重要性。 本篇文章仅做前两个小结的梳理和总结。看完这篇文章之后应该掌握容器背后的发展历史、技…