django数据关系一对多、多对多模型、自关联的建立


Posted in Python onJuly 24, 2019

一对多模型

一对多的关系,例如员工跟部门。一个部门有多个员工。那么在django怎么建立这种表关系呢?

其实就是利用外键,在多的一方,字段指定外键即可。例如员工和部门,员工是多,所以在员工表直接部门即可。

示例(见19行):

class Department(models.Model):
  name = models.CharField(max_length=20)
  create_data = models.DateField(auto_now_add=True)
  is_delete = models.BooleanField(default=False)

  class Meta:
    db_table = "department"


class Employee(models.Model):
  name = models.CharField(max_length=20)
  age = models.IntegerField()
  gender = models.IntegerField(default=0)
  # decimal_place = 2表示两位小数,max_digits表示8个数字,包括小数的两位
  salary = models.DecimalField(max_digits=8,decimal_places=2)
  # null=True 表示可以为空,blank=True表示django后台管理输入这个字段可以为空
  comment = models.CharField(max_length=300,null=True,blank=True)
  hire_data = models.DateField(auto_now_add=True)
  department = models.ForeignKey("Department")

  class Meta:
    db_table = "employee"

拓展:

1.在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:

关联属性on_delete选项的取值

  • models.CASCADE 此为默认值,级联删除,会删除关联数据
department = models.ForeignKey('Department', on_delete=models.CASCADE)
  • models.PROTECT 只要存在关联数据就不能删除
department = models.ForeignKey('Department', on_delete=models.PROTECT)
  • models.SET_NULL 删除数据后关联字段设置为NULL,仅在该字段允许为null时可用(null=True)

2.如果关联的字段不在该应用文件夹的model.py中,那么要写成这样

department = models.ForeignKey("(应用文件夹名).Department")

还有一个需要特别注意:

department = models.ForeignKey("Department",related_name='employee')时,通过部门查找员工的是用employee。如果不设置的话,是用默认的employee_set(类名的小写+_set)

一对多的查询:

一个员工所属的部门(查出来的是对象):

a = Employee.objects.get(id=1)
b = a.department

一个部门的全部员工(查出来的是对象):

a = Department.objects.get(id=1)
b = a.employee_set.all()

多对多模型

多对多的关系,例如学生与社团。一个学生可以进多个社团,一个社团可以有多个学生。那么在django怎么建立这种表关系呢?

django建立多对多关系有两种方法。

方法一:

class Student(models.Model):
  name= models.CharField(max_length=16)
  birthday=models.DateField()
class Club(models.Model):
  name= models.CharField(max_length=16)
  members = models.ManyToManyField("Student")

只需要在任意一方加上类似第6行的ManyToManyField就可以了。Django会自动为多对多关联关系创建一张表,用于两张表的联系。

那么查询呢?

1.一个社团的全部成员(查出来的是对象)

c = Club.objects.get(id=1)
c.members.all()

2.一个成员的全部社团(查出来的是对象)

s = Student.objects.filter(id=1)
s.club_set.all() # 类名的小写+_set

方法二:(比较灵活)

自己手动建立一张表关联联系。

class Student(models.Model):
  name= models.CharField(max_length=16)
  birthday=models.DateField()

class Club(models.Model):
  name= models.CharField(max_length=16)

class Membership(models.Model):
  student = models.ForeignKey("Student")
  club = models.ForeignKey("Club")

那么这种方式建表怎么查询呢?

一个学生加入的全部社团:

a = Student.objects.get(id=1)
b = a.membership_set.all() # 查出来的是对象
for i in b:
  print(i.club.name)

一个社团的全部学生:

a = Club.objects.get(id=1)
b = a.membership_set.all() # 查出来的是对象
for i in b:
  print(i.student.name)

自关联模型

自关联模型,就是表中的某一列,关联了这个表中的另外一列。最典型的自关联模型就是地区表。省、市、县都在一张表里面。省的pid为null,市的pid为省的id,县的pid为市的id。

示例:

class Area(models.Model):  
    name = models.CharField(max_length=20, verbose_name='名称')
    # 自关联(特殊的一对多): 生成的字段名 parent_id
    parent = models.ForeignKey('self', verbose_name='上级行政区划')
    class Meta:
      db_table = 'tb_areas'
      verbose_name = '行政区划'

那么,怎么查询呢?

如果知道一个市,叫a市,想查他属于什么省。

a = Area.objects.get(id=1)
# b就是a市的省份的对象
b = a.parent

如果知道一个省,叫a省,想查他有什么市。

a = Area.object.get(id=1)
# b就是a省的全部市的对象
b = a.area_set.all() #类名小写+'_set'

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详解python之多进程和进程池(Processing库)
Jun 09 Python
对numpy中布尔型数组的处理方法详解
Apr 17 Python
python方法生成txt标签文件的实例代码
May 10 Python
快速解决PyCharm无法引用matplotlib的问题
May 24 Python
Python命名空间的本质和加载顺序
Dec 17 Python
详解Python3注释知识点
Feb 19 Python
django query模块
Apr 20 Python
python中pip的使用和修改下载源的方法
Jul 08 Python
Python作用域与名字空间原理详解
Mar 21 Python
Python不支持 i ++ 语法的原因解析
Jul 22 Python
Python3爬虫mitmproxy的安装步骤
Jul 29 Python
PYTHON使用Matplotlib去实现各种条形图的绘制
Mar 22 Python
django如何自己创建一个中间件
Jul 24 #Python
django如何通过类视图使用装饰器
Jul 24 #Python
django 类视图的使用方法详解
Jul 24 #Python
django如何实现视图重定向
Jul 24 #Python
python字符串分割及字符串的一些常规方法
Jul 24 #Python
django使用haystack调用Elasticsearch实现索引搜索
Jul 24 #Python
python 判断三个数字中的最大值实例代码
Jul 24 #Python
You might like
php从右向左/从左向右截取字符串的实现方法
2011/11/28 PHP
PHP分页详细讲解(有实例)
2013/10/30 PHP
php calender(日历)二个版本代码示例(解决2038问题)
2013/12/24 PHP
php网站地图生成类示例
2014/01/13 PHP
PHP中Header使用的HTTP协议及常用方法小结
2014/11/04 PHP
PHP编程计算日期间隔天数的方法
2017/04/26 PHP
yii2.0框架数据库操作简单示例【添加,修改,删除,查询,打印等】
2020/04/13 PHP
自写简单JS判断是否已经弹出页面
2010/10/20 Javascript
仅IE9/10同时支持script元素的onload和onreadystatechange事件分析
2011/04/27 Javascript
dwz 如何去掉ajaxloading具体代码
2013/05/22 Javascript
利用js实现遮罩以及弹出可移动登录窗口
2013/07/08 Javascript
js动画效果制件让图片组成动画代码分享
2014/01/14 Javascript
编写高效jQuery代码的4个原则和5个技巧
2014/04/24 Javascript
js获取form的方法
2015/05/06 Javascript
JS+CSS实现TreeMenu二级树形菜单完整实例
2015/09/18 Javascript
JavaScript跨域调用基于JSON的RESTful API
2016/07/09 Javascript
JQuery遍历元素的后代和同胞实现方法
2016/09/18 Javascript
微信小程序教程系列之新建页面(4)
2017/04/17 Javascript
浅谈sass在vue注意的地方
2017/08/10 Javascript
在 Typescript 中使用可被复用的 Vue Mixin功能
2018/04/17 Javascript
vue实现行列转换的一种方法
2019/08/06 Javascript
jQuery实现验证用户登录
2019/12/10 jQuery
微信小程序button标签open-type属性原理解析
2020/01/21 Javascript
linux 下实现python多版本安装实践
2014/11/18 Python
详解Python的Django框架中的中间件
2015/07/24 Python
python requests证书问题解决
2019/09/05 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
python实现百度OCR图片识别过程解析
2020/01/17 Python
Python爬虫之Selenium实现关闭浏览器
2020/12/04 Python
新秀丽拉杆箱美国官方网站:Samsonite美国
2016/07/25 全球购物
NFL墨西哥官方商店:Tienda NFL
2017/11/28 全球购物
执行力心得体会
2013/12/31 职场文书
党员学习中共十八大思想报告
2014/09/12 职场文书
报表员工作失误检讨书范文
2014/09/19 职场文书
Mysql 如何实现多张无关联表查询数据并分页
2021/06/05 MySQL
使用python绘制横竖条形图
2022/04/21 Python