对于数据库来说一般表结构只会有三种对应关系,分别是一对一、一对多和多对一,下面分别介绍:

1.一对多

何为一对多,例如一个学生只可能有一个班级,一个班级却又多个学生,班级表和学生表就是一对多的关系。

在查询信息的时候有两种方式:正向查询和反向查询。

(1)正向查询

models.Student.objects.first()
<Student: Student object>#返回一个学生对象
models.Student.objects.first().sname #可以查询学生信息
'科比'
models.Student.objects.first().cid #由于有关联,可以直接获取班级对象
<Class: Class object>
models.Student.objects.first().cid.cname #查询班级属性
'全栈6期'
models.Student.objects.first().cid.first_day
datetime.date(2017, 7, 14)

(2)反向查询

models.Class.objects.filter(id=3)
<QuerySet [<Class: Class object>]>
#这是一个班级Queryset models.Class.objects.filter(id=3)[0]
<Class: Class object>
#获取班级对象 models.Class.objects.filter(id=3)[0].cname
'全栈8期'
#既然是对象就可以查看相关属性 models.Class.objects.filter(id=3)[0].student_set
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x0000019A6A928FD0>
#反向查找学生,获取学生集合,这是Django自己的模式 models.Class.objects.filter(id=3)[0].student_set.all()
<QuerySet [<Student: Student object>, <Student: Student object>]>
#查看集合中所有的对象 models.Class.objects.filter(id=3)[0].student_set.all().values()
<QuerySet [{'id': 8, 'sname': '小鸟', 'cid_id': 3}, {'id': 11, 'sname': '大爷', 'cid_id': 3}]>
#可以进一步查看相关属性

注意:

如果不在外键的字段中设置related_name的话,默认就用表名_set.

如果设置了related_name=“students”,反向查找时可以直接使用student进行反向查找。

>>> class_obj.students.all()
#直接获取班级中的学生,而不需要set

2.一对一

表结构设计

class Student(models.Model):
id = models.AutoField(primary_key=True)
sname = models.CharField(max_length=32)
cid = models.ForeignKey("Class")
detail = models.OneToOneField(to="StudentInfo", null=True) class StudentInfo(models.Model):
height = models.CharField(max_length=4)
weight = models.CharField(max_length=4)
addr = models.CharField(max_length=32,null=True)

(1)正向查询

models.Student.objects.first()
<Student: Student object>
#获得一个对象 models.Student.objects.first().detail.addr
'罗田'
#正向查询获取属性,通过关联字段直接找

(2)反向查询

models.StudentInfo.objects.filter(height=180)
<QuerySet [<StudentInfo: StudentInfo object>]>
#获得一个Queryset models.StudentInfo.objects.filter(height=180)[0].student
<Student: Student object>
#反向查找学生,返回一个对象 models.StudentInfo.objects.filter(height=180)[0].student.sname
'小鸟'
#查看学生信息

3.多对多

1)创建多对多的对应关系有三种方法:

(1)通过外键创建

class Class(models.Model):
id = models.AutoField(primary_key=True) # 主键
cname = models.CharField(max_length=32) # 班级名称
first_day = models.DateField() # 开班时间 class Teacher(models.Model):
tname = models.CharField(max_length=32) # 自定义第三张表,通过外键关联上面两张表
class Teacher2Class(models.Model):
teacher = models.ForeignKey(to="Teacher")
the_class = models.ForeignKey(to="Class") class Meta:
unique_together = ("teacher", "the_class") #指定联合唯一

(2)通过ManyToManyField创建

class Class(models.Model):
id = models.AutoField(primary_key=True) # 主键
cname = models.CharField(max_length=32) # 班级名称
first_day = models.DateField() # 开班时间 class Teacher(models.Model):
tname = models.CharField(max_length=32)
# 通过ManyToManyField自动创建第三张表
cid = models.ManyToManyField(to="Class", related_name="teachers")

这种方法会自动生成一张对应表,但是不能使用多对多的众多方法。

(3)通过外键和ManyToManyField创建

class Class(models.Model):
id = models.AutoField(primary_key=True) # 主键
cname = models.CharField(max_length=32) # 班级名称
first_day = models.DateField() # 开班时间 class Teacher(models.Model):
tname = models.CharField(max_length=32)
# 通过ManyToManyField和手动创建第三张表
cid = models.ManyToManyField(to="Class", through="Teacher2Class", through_fields=("teacher", "the_class")) class Teacher2Class(models.Model):
teacher = models.ForeignKey(to="Teacher")
the_class = models.ForeignKey(to="Class") class Meta:
unique_together = ("teacher", "the_class")

貌似这种方法最为靠谱,但是最麻烦。

2)查询的方法

(1)正向查询(由老师表查询班级)

models.Teacher.objects.first()
<Teacher: Teacher object>
#获取一个老师的对象 models.Teacher.objects.first().cid
<django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x000001FE3916A518>
#获取老师所对应的班级 models.Teacher.objects.first().cid.all()
<QuerySet [<Class: Class object>, <Class: Class object>]>
#获取所有班级对象 models.Teacher.objects.first().cid.all().values()
<QuerySet [{'id': 1, 'cname': '全栈6期', 'first_day':
datetime.date(2017, 7, 14)}, {'id': 3, 'cname': '全栈8期', 'first_day': datetime.date(2017, 10, 17)}]>
#查看所有值

为什么能够直接找到班级?

答案是:通过关联字段

(2)反向查询(由班级表反向查询老师表)

models.Class.objects.first()
<Class: Class object>
#获取班级对象 models.Class.objects.first().teachers
<django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x000001FE3918C390> models.Class.objects.first().teachers.all().values()
<QuerySet [{'id': 1, 'tname': '爱根'}, {'id': 4, 'tname': '日天'}, {'id': 6, 'tname': '银角大王'}]>
#由班级反向查老师 models.Class.objects.first().teachers.all()
<QuerySet [<Teacher: Teacher object>, <Teacher: Teacher object>, <Teacher: Teacher object>]>

刚才正向查找的时候,是因为老师表种由cid这个字段,所以可以直接查找,但是现在这个是怎么关联上的了?请看下面

cid = models.ManyToManyField(to="Class", related_name="teachers")

关联的时候设置了related_name,所以可以反向查找。

注意:这里不能使用teacher_set这种方式,而在一对多种可以使用

来看看各种对应关系的正向查找:

#一对多正向查找(学生表——》班级表)
models.Student.objects.first().cid #一对一正向查找(学生表——》学生信息表)
models.Student.objects.first().detail.addr #多对多正向查找(老师表到班级表)
models.Teacher.objects.first().cid.all() #正向查找是表中必须有的字段

来看看各种对应关系的反向查找:

反向查找是相对于正向查找来说的。

#一对多反向查找(班级表——》学生表)
models.Class.objects.filter(id=3)[0].student_set.all() #一对一反向查找(后面直接可查属性)(学生信息表——》学生表)
models.StudentInfo.objects.filter(height=180)[0].student #多对多反向查找(班级表——》老师表)
models.Class.objects.first().teachers.all()

Django模型系统——ORM表结构对应关系的更多相关文章

  1. Django模型系统——ORM中跨表、聚合、分组、F、Q

    核心知识点: 1.明白表之间的关系 2.根据关联字段确定正反向,选择一种方式 在Django的ORM种,查询既可以通过查询的方向分为正向查询和反向查询,也可以通过不同的对象分为对象查询和Queryse ...

  2. Django模型系统——ORM

    一.概论 1.ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描 ...

  3. Django模型系统——ORM校园管理系统代码

    1.models.py from django.db import models # Create your models here. class Class(models.Model): id = ...

  4. django模型系统(一)

    django模型系统(一) djangode ORM ORM:对像关系映射 用python概念去表达数据库 数据库配置(mysql) 安装pumysql 修改项目目录下的__init__.py imp ...

  5. django模型系统(二)

    django模型系统(二) 常用查询 每一个django模型类,都有一个默认的管理器,objects QuerySet表示数据库中对象的列表.他可以有0到国歌过滤器.过滤器通过给定参数,缩小查询范围( ...

  6. 25 Zabbix系统数据表结构介绍

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 25 Zabbix系统数据表结构介绍 自学Zabbix之路15.1 Zabbix数据库表结构简单解 ...

  7. 利用flask-sqlacodegen快速导入ORM表结构

    利用flask-sqlacodegen快速导入ORM表结构 友情提示:如果是使用pymysql请预先pip install 哦~ 这是window下使用virtualenv环境下执行的 Linux用户 ...

  8. 八.django模型系统(二)之常用查询及表关系的实现

    Ⅰ.常用查询  1.几个概念 每一个django模型类,都有一个默认的管理器,objects,查询就是依赖于objects管理器进行的(在创建时就被添加了). QuerySet表示数据库中对象的列表( ...

  9. Django之django模型层一单表操作

    一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...

随机推荐

  1. ESLint检测JavaScript代码

    1.安装 有2中安装方式:全局安装和局部安装. 局部安装方式为: (1)cnpm install -g eslint (2)打开项目目录.配置eslint文件 eslint --init (3)执行e ...

  2. 【BIEE】页面跳转以及跳转后返回

    报表开发过程中,我们经常会遇到这种问题:知道统计结果,然后根据统计结果去看明细数据 很多人可能首先想到的就是钻探,钻探是一种方法,但是不是唯一的办法,可以使用页面跳转完成. 下面举个例子 页面A 现在 ...

  3. 快速接入 Android BLE 开发的基础框架

    代码地址如下:http://www.demodashi.com/demo/12092.html ** Android BLE基础操作框架,基于回调,操作简单.包含扫描.多连接.广播包解析.服务读写及通 ...

  4. [django] 利用多线程添加异步任务

    看到django异步大家的反应应该是celery这样的消息队列组件.如今用的最多的最推荐的也是这样的方式.然而我这需求就是请求来了,运行一个小程序.可是又不能确定这个小程序啥时候运行完.响应又要及时, ...

  5. 【.net项目中。。】.net一般处理程序使用方法

    1.基本原理图 IsReusable属性用来表示在IHttpHandlerFactory对象创建IHttpHandler的时候是否能够将这个Handler存入池中以便重用. 一般处理程序(HttpHa ...

  6. Element type &quot;Resource&quot; must be followed by either attribute specifications, &quot;&gt;&quot; or &quot;/&gt;&quot;.

    在xml中配置没有问题的情况下.检查是否有单词中间缺少 空格 .2个单词靠的太近的情况! 试了一下情况解决!

  7. C# virtual,override,new 整理

    今天仔细学习了一下C#中virtual, override, new关键字,参考了网上的很多资料,现整理一下. Virtual: virtual 关键字用于修饰方法.属性.索引器或事件声明,并使它们可 ...

  8. 机器学习12—FP-growth学习笔记

    test12.py #-*- coding:utf-8 import sys sys.path.append("fpGrowth.py") import fpGrowth from ...

  9. Spring在注入bean异常时的替换

    情形:需要把数据库1的连接池A注入到DAO中,但是如果数据库A的连接池实例化失败了整个项目也启动不了,这个时候希望用数据库2的连接池来替换. 这里没有想到什么好的解决方法,只是想到了工厂方法提供Bea ...

  10. PHP运行环境之IIS FastCGI 进程意外退出解决办法

    本机做了系统,结果之前装好的APACHE环境什么的都没了,不想费事了,这次直接使用WIN8自带的IIS功能了,安装完毕后提示FastCGI 进程意外退出解决办法,这是由于某些加载库加载失败的原因,这里 ...