本章节将介绍ORM中的关联模型,以下测试基于book管理

一、创建关联模型

创建app01并注册

编辑全局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',    ###添加app01的配置
]

配置数据库连接

编辑全局settings.py文件,如下:

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'Django','USER': 'root','PASSWORD': '123456','HOST': 'locahost','PORT': '3306',}
}

创建关联模型

编辑app01下的models.py文件,如下:

from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=32)price = models.DecimalField(max_digits=8, decimal_places=2)  # 999999.99,浮点型8位数,小数点2位publishDate = models.DateField()# 一对多的关联属性,创建关联字段publish = models.ForeignKey("Publish", on_delete=models.CASCADE)   ###表中会添加一个publish_id字段,并设置级联删除# 多对多的关联属性,创建关系表authors = models.ManyToManyField("Author", db_table="book2author")  # 多对多的时候,一般通过第三方表来实现,如果不命名的话,会自动创建一个book_authors的表class Publish(models.Model):name = models.CharField(max_length=32)addr = models.CharField(max_length=32)email = models.CharField(max_length=32)class Author(models.Model):name = models.CharField(max_length=32)age = models.SmallIntegerField()###设置一对一的关联属性ad = models.OneToOneField("AuthorDetail", on_delete=models.CASCADE)   ##添加ForeignKey时需设置级联删除。class AuthorDetail(models.Model):tel = models.IntegerField()addr = models.CharField(max_length=32)

具体解释如下:

  • 一对多
在一对多的关系中,需要使用models.ForeignKey在表示“多”的模型中定义一个外键字段,定义时需要指定表示“一”的模型类名。models.ForeignKey常用参数:
-   to:该属性的第一个参数,表示外键指向的模型类的类名
-   on_delete:表示外键指向的数据不存在时,本条数据该如何处理。-  CASCADE:级联操作,如果外键对应的在另一张表中的数据被删除了,那么本条数据也会被跟着删除。- PROTECT:外键数据受保护,即只要本条数据还存在,则外键对应的在另一张表中的数据是无法被删除的。-   SET_NULL:删除时设置为空,如果外键对应的在另一张表中的数据被删除了,那么本条数据中的这个外键值就设置为空。-    SET_DEFUALT:设置为默认值,如果外键对应的在另一张表中的数据被删除了,那么本条数据中的这个外键值就设置为指定的默认值,但前提是此字段有指定的默认值。-   SET(obj/func):设置默认值,如果外键对应的在另一张表中的数据被删除了,那么本条数据中的这个外键值就设置为指定的值obj或者指定函数或方法func的返回值。-  DO_NOTHING:不做任何操作,一切只看数据库本身的约束。
-   related_name: 一般用于反向查询,表示“多”的模型中定义外键后,Django会在表示“一”的模型中自动生成一个表示“多”的模型类名_set属性,如果不想使用这种默认的命名方式,就可以使用此参数指定自己需要的名称了。 -   db_constraint:默认为True,指有外键约束,如果只想设置关联数据,取消外键约束,设置为Flase即可。

参考related.py文件,如下定义的ForeignKey方法:

def __init__(self, to, related_name=None, related_query_name=None,limit_choices_to=None, symmetrical=None, through=None,through_fields=None, db_constraint=True, db_table=None,swappable=True, **kwargs):try:to._metaexcept AttributeError:assert isinstance(to, str), ("%s(%r) is invalid. First parameter to ManyToManyField must be ""either a model, a model name, or the string %r" %(self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT))
  • 多对多
使用models.ManyToManyField指定即可(定义多对多关系时,Django会在数据库中自动生成一个关联两张表的中间表,但是在Django中不用我们自己去定义),同样的,也会在另一个模型中自动生成一个形如类名_set的属性。
  • 一对一
使用models.OneToOneField指定即可,定义方法和参数使用与models.ForeignKey类似(因为models.OneToOneField就是通过models.ForeignKey来实现的,只不过是添加了一个“唯一”的约束),不同之处在于,在另一个外键对应的模型中自动生成的属性为类名的小写形式,当然,你不想用默认生成的属性,也可以通过related_name参数来指定。

添加数据

在models.py文件中添加如下内容:

AuthorDetail.objects.create(tel=122121212,addr="北京")
AuthorDetail.objects.create(tel=212121212,addr="南京")
AuthorDetail.objects.create(tel=313131313,addr="上海")
Publish.objects.create(name="北京出版社",addr="昌平",email="122122")
Publish.objects.create(name="南京出版社",addr="中山路",email="212122")
Publish.objects.create(name="上海出版社",addr="浦东",email="313313133")

执行数据库迁移

python manage.py makemigrations    ###生成迁移文件
python manage.py migrate           ###同步数据库

二、关联模型操作

一对多增删改查

  • 创建路由
    编辑全局配置文件urls.py文件,如下:
from django.contrib import admin
from django.urls import path
from app01 import views as app1
urlpatterns = [path('admin/', admin.site.urls),path('index',app1.addbook),]
  • 增加
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):##向book表中添加一条数据##获取出版社名称publish = Publish.objects.get(name="北京出版社")##方法一book = Book.objects.create(title="西游记",price=100,publishDate="2022-12-2",publish=publish)###方法二book = Book.objects.create(title="红楼梦", price=200, publishDate="2021-11-2", publish_id=5)book = Book.objects.create(title="水浒传", price=180, publishDate="2020-10-2", publish_id=6)###打印相关内容print(book1.title)      ###book对象中title已经复制到内存中print(book1.publish)    ###打印结果为一个对象print(book1.publish.name)   ###Django关联模型中会利用publish_id获得publish(get方式)的模型类对象print(book1.publish_id)   ##得到的就是当前book记录的publish_id,return HttpResponse("成功")

运行django程序,界面登录,查看数据库添加成功

  • 删除
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):##将book表中删除一条数据Book.objects.filter(title="西游记").delete()   ##直接删除即可return HttpResponse("成功")

  • 更新
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):##更新表中的数据Book.objects.filter(title="红楼梦").update(name="三国演义")   ##直接更新return HttpResponse("成功")

  • 查看
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):##查看表中的数据book = Book.objects.filter(name="三国演义") ##和之前讲的一样,就不再次赘述print(book)return HttpResponse("成功")

多对多增删改查

  • 增加
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):##为book书籍添加作者##方法一##获取book信息book = Book.objects.get(title="水浒传")author1 = Author.objects.get("小华")author2 = Author.objects.get(name="小明")book.authors.add(author1, author2)##方法二book = Book.objects.get(title="水浒传")book.authors.add(1, 2)      ###可以直接跟authorID##方法三book = Book.objects.get(title="水浒传")author_list = [1,2]    ###将作者定义为列表book.authors.add(*author_list)    ##将列表中的数据传进去return HttpResponse("成功")

运行django程序,查看第三张关联表,如下:

  • 删除
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):###删除书的作者book = Book.objects.get(title="水浒传")book.authors.remove(2)   ###删除指定作者对象####book.authors.clear()    ###删除该book下关联的所有作者对象return HttpResponse("成功")
  • 修改
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):###更新书的作者book = Book.objects.get(title="水浒传")book.authors.set([6,])   ###先clear删除后add添加return HttpResponse("成功")

运行django程序,查看结果

也可以看到sql的运行过程,是先根据bookIDapp01_author表中查出来该book对应的author的信息,在进行delete删除,之后进行insert添加,如下:

  • 查看
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):###查询书的作者book = Book.objects.get(title="水浒传")author_list = book.authors.all().values("name","age")print(author_list)return HttpResponse("成功")

运行django程序,结果如下:

一对一增删改查

此处不多讲,只演示如何添加数据

from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):##添加一条作者信息author = Author.objects.create(name="小华",age=40,ad_id=3)return HttpResponse("成功")

反向查询

前面介绍的都是基于book查看author,下面来介绍如何基于author查看book
上面说到创建多对多关联模型的时候,添加了related_name="books"参数,后面的名字可以随意定义
具体步骤如下:
from django.shortcuts import render,HttpResponse,redirect
from app01.models import Book,Publish,Author,AuthorDetail
def addbook(request):###反向查询###通过作者查出对应的书籍authtor = Author.objects.get(pk=6)   ###获取author的信息print(authtor.books.all().values("title"))    ###通过author调用books对象获取book信息return HttpResponse("成功")

大致原理如下:

1: 通过定义的related_name得知是和哪张表是多对多的关系
2: 然后通过第三张关联表的authorID获取所有的book信息
3:通过获取的book对象来查找具体的哪个属性的信息

运行django程序,结果如下:

查看数据库中的数据,结果一致,如下:

六、Django ORM关联模型相关推荐

  1. django orm关联查询_django中orm的多表查询

    一.创建模型 下面我们通过图书管理系统,来设计出每张表之间的对应关系. 通过上图关系,来定义一下我们的模型类. from django.db import models class Book(mode ...

  2. django orm关联查询_Django ORM 聚合查询和分组查询实现详解

    models.py: from django.db import models # 出版社 class Publisher(models.Model): id = models.AutoField(p ...

  3. django ORM中的RelatedManager(关联管理器)

    关联管理器应用在 一对多的表 或者 多对多的表 多对多表中的用法: 在多对多的表中 正向查询 #基于对象的查询 #正查 # author_obj = Author.objects.get(id=1) ...

  4. Django ORM – 多表实例:Django模型Model的定义+模型间关系

    Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle. Django 为这些数据库提供了统一的调用API. 我们可以根据自己业务需求选择不同的 ...

  5. django orm原理_django 动态创建一个模型的多个table name, 并通过 Django ORM 操作

    动态创建table, 并通过 Django ORM 操作. 动态的创建表 动态的创建模型其实就是在运行时生成 Model 类, 这个可以通过函数实现, 通过传参(今天的日期, 如: 20181211) ...

  6. Django - ORM操作

    Django - ORM操作 一. 必知必会13条 单表查询之神奇的双下划线 二. ForeignKey操作 正向查找 反向操作 三. ManyToManyField 四. 聚合查询和分组查询 聚合 ...

  7. Django框架的模型层之多表操作

    目录 一 创建模型 二 表记录的增删改 一对多 多对多 三.基于对象的跨表查询 一对一查询(Author 与 AuthorDetail) 一对多查询(publish与book) 多对多查询 (Auth ...

  8. django orm级联_Django数据表关联关系映射(一对一、一对多、多对多)

    我们知道涉及到数据表之间的对应关系就会想到一对一.一对多.多对多,在学习 MySQL 数据库时表关系设计是需要重点掌握的知识.Django 中定义了三种关系类型的字段用来描述数据库表的关联关系:一对多 ...

  9. django ORM相关的那些操作汇总

    必知必会13条 <1> all(): 查询所有结果<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象<3> get(**kwargs): ...

最新文章

  1. OpenSCAD 建模:矿泉水瓶盖
  2. 文件资源管理右键卡死无响应
  3. 射雕三部曲的优美片段
  4. Python 字符串 String 内建函数大全(1)
  5. spring elasticsearch 按条件删除_SpringBoot2 高级案例(08):整合 ElasticSearch框架,实现高性能搜索引擎...
  6. mysql 游标的简单_mysql 简单游标
  7. 【JAVA】Java中goto语句的简介与使用(java 如何跳出内嵌多层循环的方法)
  8. Matlab标准语音库 Timit Database
  9. “C语言” 读书札记(五)之[让我们一起学习汇编吧!(段)]
  10. insmod module 失败(skyeye + armlinux)
  11. 百度远场语音识别套件-开箱评测
  12. 【BZOJ 3681】Arietta
  13. Winform 调整SplitContainer中Panel的大小
  14. Ubuntu磁盘分区和挂载
  15. MongoDB分片机制
  16. Java13新增特性
  17. 上传资料总是显示服务器异常,云盘上传总是服务器异常
  18. 【学习周报】深度学习笔记第二周
  19. 高仿Telegram IM Chat 聊天软件 即时通讯 在线聊天加社群 纯静态UI架构介绍
  20. 并行算法设计与性能优化 刘文志 第2章 现代处理器特性

热门文章

  1. 计算机视觉的最终表现!三维重建技术
  2. 西方哲学智慧2018网课考题(本人亲测,已满分)
  3. PYTHON第二次实验
  4. 小红书api_【实习精选】oppo、小红书等名企实习汇总(96)
  5. BZOJ4765 普通计算姬
  6. 《Android游戏编程入门经典》——1.1节Android 4简介
  7. 计算机专业论文 方向,计算机专业本科生方向论文题目 计算机专业本科生论文题目怎样取...
  8. Android中InCallUI显示太慢问题分析
  9. YSO小游戏·VB6版代码
  10. 【我的DOT语言学习之旅】 学习DOT语言并使用Graphviz软件来打开.dot文件