首先来创建一个模型,数据库的关系就清楚了

models.py

from django.db import models

# Create your models here.

class Author(models.Model):

    id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField()
au = models.OneToOneField(to='AuthorDetail',to_field='id',on_delete=models.CASCADE) class AuthorDetail(models.Model): id = models.AutoField(primary_key=True)
address = models.CharField(max_length=32)
tel = models.CharField(max_length=11) class Publish(models.Model): id = models.AutoField(primary_key=True)
name = models.CharField(max_length=22)
addr = models.CharField(max_length=64) class Book(models.Model): id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publisher = models.ForeignKey(to='Publish',to_field='id',on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')

一.创建模型

  一对一创建

    obj = models.onetooneField(to='表名', to_Field='字段')

  一对多创建

    obj = models.Foreignkey(to='表名', to='字段名', on_delete=models.CASCADE)

  多对多创建

    obj = models.manytomanyField(to='表名')

二.添加数据

  一对一添加

    models.Author.objects.create(
    name = '太宰治',
    age = 18,
     author_id = 1
    )

  一对多添加

    方式1, 用对象的方式创建

    publish_obj = Publisht.objects.get(id=1)  # 拿到id为1的出版社对象
    book_obj = Book.objects.create(
      title='人间失格',
      publish = publish_obj,
    )

    方式2, 直接指定字段名称创建

    book_obj = Book.objects.create(
      title='人间失格',
      publish_id=1,
    )

  多对多添加

    方式1

    book_obj = models.Book.objects.filter(id=4)[0]
    lzs = models.Author.objects.get(id=1)
    ws = models.Author.objects.get(id=2)     book_obj.authors.add(lzs,ws)

    方式2

    book_obj.authors.add(*[1,2])
    book_obj.authors.add(1,2)

    其他常用API:

     book_obj.authors.remove()      # 将某个特定的对象从被关联对象集合中去除。 book_obj.authors.remove(*[1,2]),将多对多的关系数据删除
     book_obj.authors.clear() #清空被关联对象集合
     book_obj.authors.set() #先清空再设置(更新)

三.删除数据

  一对一、一对多的删改和单表的删改是一样的,因为在models里面我们设置了级联删除

    models.Author.objects.filter(id=1).delete()
    models.Book.objects.filter(id=1).delete()
    book_obj.authors.clear()
    book_obj.authors.remove('')

  多对多删除,用到的

    book_obj.authors.remove() 

三.基于对象的跨表查询

  正向查询与反向查询

    外键字段在哪个表中,它找别人就是正向查询

    别的表找它就是反向查询

  一对一查询(Author表和AuthorDetail): 

    正向查询按字段,反向查询用表名小写

      1 查询名为太宰治的作者的电话号码
      ret = models.Author.objects.get(name='太宰治')
          models.Author.objects.get(name='太宰治').au.address
          models.Author.objects.filter(name='太宰治')[0].au.address
      a = ret.au.tel       2 查询电话号码为111的作者的名称
      ret = models.AuthorDetail.objects.get(tel=111)
      a = ret.author.name

  一对多查询(Publish表与Book表)

    正向查询按字段,反向查询用表名小写_set.all()

    正向查询:

      # 查询主键为1的书籍的出版社所在的城市
      book_obj=Book.objects.filter(pk=1).first()
      # book_obj.publish 是主键为1的书籍对象关联的出版社对象,book对象.外键字段名称
      print(book_obj.publish.city)  

    反向查询: book_set().all()

      publish=Publish.objects.get(name="太阳出版社")
      #publish.book_set.all() : 与苹果出版社关联的所有书籍对象集合,写法:小写的表名_set.all(),得到queryset类型数据
      book_list=publish.book_set.all()
      for book_obj in book_list:
    print(book_obj.title)

  多对多查询:(Author表和Book表)

    正向查询

      # 人间失格所有作者的名字以及手机号

      book_obj=Book.objects.filter(title="人间失格")[0]
      authors=book_obj.authors.all()
      for author_obj in authors:
      print(author_obj.name,author_obj.authorDetail.telephone)

    反向查询

      # 查询太宰治出过的所有书籍的名字

        author_obj=Author.objects.get(name="太宰治")
    book_list=author_obj.book_set.all() #与太宰治作者相关的所有书籍
    for book_obj in book_list:
    print(book_obj.title)

四.基于双下划线的跨表查询

  相当于基于join的联表查询,效率较高,用法是正向按属性(models.py中定义的),反向按表名.

  一对一查询

  #查询太宰治的手机号

  #正向查询
  ret=Author.objects.filter(name="太宰治").values("au__tel")   #反向查询
  ret=AuthorDetail.objects.filter(author__name="太宰治").values("tel")

  一对多查询

  查询太阳出版社出版过的所有书籍的名字与价格(一对多) 

    # 正向查询 按字段:publish

  queryResult=Book.objects.filter(publish__name="太阳出版社").values_list("title","price") #values或者values_list
  #通过__告诉orm将book表和publish表进行join,然后找到所有记录中publish.name='苹果出版社'的记录(注意publish是属性名称),
  然后select book.title,book.price的字段值 # 反向查询 按表名:book queryResult=Publish.objects.filter(name="太阳出版社").values_list("book__title","book__price")

  多对多查询

  #查询太宰治出过的所有书籍的名字(多对多)

  # 正向查询 按字段:authors:
  queryResult=Book.objects.filter(authors__name="太宰治").values_list("title")   # 反向查询 按表名:
bookqueryResult=Author.objects.filter(name="太宰治").values_list("book__title","book__price")

五.修改数据

  修改数据使用update() 用queryset类型来调用

  models.Book.objects.filter(title='太宰治').update(title='村上春树')

  修改多对多对象的关系

 models.Book.objects.filter(title='太宰治')[0].set(*[1,2])

django系列5.3--ORM数据库的多表操作的更多相关文章

  1. Django之模型层第一篇:单表操作

    Django之模型层第一篇:单表操作 一 ORM简介 ​ 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数 ...

  2. Django之模型层第二篇:多表操作

    Django之模型层第二篇:多表操作 一 表关系回顾 ​ 在讲解MySQL时,我们提到,把应用程序的所有数据都放在一张表里是极不合理的. ​ 比如我们开发一个员工管理系统,在数据库里只创建一张员工信息 ...

  3. 第69节:Java中数据库的多表操作

    第69节:Java中数据库的多表操作 前言 学习数据库的多表操作,去电商行业做项目吧!!! 达叔,理工男,简书作者&全栈工程师,感性理性兼备的写作者,个人独立开发者,我相信你也可以!阅读他的文 ...

  4. 数据库 MySQL 之 表操作、存储引擎

    数据库 MySQL 之 表操作.存储引擎 浏览目录 创建(复制) 删除 修改 查询 存储引擎介绍 一.创建(复制) 1.语法: 1 2 3 4 5 CREATE TABLE 表名(     字段名1 ...

  5. Day 61 Django第二天 (orm数据库操作)

    一.get请求和post请求 GET请求: 1. 浏览器请求一个页面 2. 搜索引擎检索关键字的时候 POST请求: 1. 浏览器向服务端提交数据,比如登录/注册等 二 . Django中的APP: ...

  6. django系列5.1--ORM对数据库的操作

    Django---ORM数据库操作(图书管理系统基本实例) 一.基本知识 MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Mo ...

  7. django系列5.2--ORM数据库的单表操作

    单表操作 在views.py中添加对数据库的操作语句 #在逻辑代码中导入你要操作的表 from app import models def add_book(request): ''' 添加表记录 : ...

  8. web框架开发-Django模型层(1)之ORM简介和单表操作

    ORM简介 不需要使用pymysql的硬编码方式,在py文件中写sql语句,提供更简便,更上层的接口,数据迁移方便(有转换的引擎,方便迁移到不同的数据库平台)…(很多优点),缺点,因为多了转换环节,效 ...

  9. django连接mysql数据库以及建表操作

    django连接mysql数据库需要在project同名的目录下面的__init__.py里面加入下面的东西 import pymysql pymysql.install_as_MySQLdb() 找 ...

  10. 模型层之ORM、数据库和单表操作

    一.ORM简介 ORM是“对象-关系-映射”的简称,一般指持久化数据和实体对象的映射 1.1 什么是“持久化” 持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中( ...

随机推荐

  1. 合并SCVMM虚拟机的差异磁盘,并删除那些难以删除的Checkpoints(Shapshots)

    使用Microsoft Data Protection Manager(DPM)有时会造成虚拟机的动态和固定磁盘变成差异磁盘,这个应该与DPM进行差异备份有关,未知原因造成DPM差异备份后无法复原原来 ...

  2. CImage 往Picture Control贴图 图像显示不正常

    在使用CImage 往vc控件 picture Control 上贴图的时候图像显示不太正常如图: 已知原始图片的宽高为640*640  而我上面picture Control  控件宽高小于原始图像 ...

  3. spring错误处理 Build path is incomplete. Cannot find class file for org.springframework.aop.Advisor

    Build path is incomplete. Cannot find class file for org.springframework.aop.Advisor 初学spring,记录一下出现 ...

  4. ubuntu server 安装nextcloud12

    1.更新系统安装必要的依赖包 [user]$ sudo apt-get update && sudo apt-get -y upgrade [user]$ sudo apt-get i ...

  5. ios的@property属性和@synthesize属性(转)

    当你定义了一系列的变量时,需要写很多的getter和setter方法,而且它们的形式都是差不多的,,所以Xcode提供了@property 和@synthesize属性,@property用在 .h ...

  6. c语言二维数组与指针

    问题,以下输出的结果是什么,区别在于哪? void main() { ][] = { ,,,,,,,,,,, }; //输出的3个地址都一样,差别在哪? printf("\n%x" ...

  7. mybatis总结回顾

    1.mybatis的介绍 轻量级数据持久层框架,替代hibernate 2.mybatis的入门 导包-->配置文件(类名.xml.SqlMapConfig.xml) 类名.xml:放映射.sq ...

  8. TableLayout 里的TextView等组的LayoutParams参数问题

    TableLayout 里的TextView等组的LayoutParams参数不能是LinearLayout.LayoutParams这样来定义, 只能是用TableRow.LayoutParams ...

  9. [原创]解决IPCH关闭后可能引发的无法调试的BUG

    前几天清理硬盘,发现大量IPCH目录,文件特别巨大,看着头大,所以决定改为临时模式,同时VS2015和VS2013我都改了,设置如下: (关键字:IPCH目录,VS大文件) 当设置好之后不会出现烦人的 ...

  10. java类加载器的一些测试

    package classloader; import java.lang.reflect.Method; import org.junit.Test; import com.example.Samp ...