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文件夹与文件的操作实现代码
Jul 13 Python
跟老齐学Python之有容乃大的list(4)
Sep 28 Python
Python中的is和id用法分析
Jan 26 Python
windows下Virtualenvwrapper安装教程
Dec 13 Python
关于python写入文件自动换行的问题
Jun 23 Python
pycharm运行程序时在Python console窗口中运行的方法
Dec 03 Python
Python实现FM算法解析
Jun 18 Python
Python 共享变量加锁、释放详解
Aug 28 Python
python主线程与子线程的结束顺序实例解析
Dec 17 Python
Python 实现一行输入多个数字(用空格隔开)
Apr 29 Python
2020年10款优秀的Python第三方库,看看有你中意的吗?
Jan 12 Python
浅谈Python协程asyncio
Jun 20 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中鲜为人知的10个函数
2014/02/28 PHP
PHP函数extension_loaded()用法实例
2015/01/19 PHP
php+ajax实现的点击浏览量加1
2015/04/16 PHP
面向对象的编程思想在javascript中的运用上部
2009/11/20 Javascript
javascript new一个对象的实质
2010/01/07 Javascript
node.js中的url.parse方法使用说明
2014/12/10 Javascript
Javascript基础教程之if条件语句
2015/01/18 Javascript
jQuery实现为图片添加镜头放大效果的方法
2015/06/25 Javascript
css如何让浮动元素水平居中
2015/08/07 Javascript
JavaScript隐式类型转换
2016/03/15 Javascript
基于jQuery Tipso插件实现消息提示框特效
2016/03/16 Javascript
Javascript之面向对象--封装
2016/12/02 Javascript
jQuery Easyui加载表格出错时在表格中间显示自定义的提示内容
2016/12/08 Javascript
Angular.js自定义指令学习笔记实例
2017/02/24 Javascript
微信小程序中页面FOR循环和嵌套循环
2017/06/21 Javascript
JavaScript实现二维坐标点排序效果
2017/07/18 Javascript
JavaScript中Hoisting详解 (变量提升与函数声明提升)
2017/08/18 Javascript
Vue2.0 事件的广播与接收(观察者模式)
2018/03/14 Javascript
通过jquery获取上传文件名称、类型和大小的实现代码
2018/04/19 jQuery
vue 使用 canvas 实现手写电子签名
2020/03/06 Javascript
小程序实现tab标签页
2020/11/16 Javascript
JQuery绑定事件四种实现方法解析
2020/12/02 jQuery
[45:18]完美世界DOTA2联赛循环赛 PXG vs IO 第二场 11.06
2020/11/09 DOTA
使用django-suit为django 1.7 admin后台添加模板
2014/11/18 Python
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
python游戏地图最短路径求解
2019/01/16 Python
简单了解django缓存方式及配置
2019/07/19 Python
Python搭建代理IP池实现存储IP的方法
2019/10/27 Python
python实现将range()函数生成的数字存储在一个列表中
2020/04/02 Python
canvas生成带二维码海报的踩坑记录
2019/09/11 HTML / CSS
英国马莎百货印度官网:Marks & Spencer印度
2020/10/08 全球购物
乡镇创先争优活动总结
2014/08/28 职场文书
社区助残日活动总结
2014/08/29 职场文书
2015年世界环境日活动总结
2015/02/11 职场文书
你会写请假条吗?
2019/06/26 职场文书
vue+elementui 实现新增和修改共用一个弹框的完整代码
2021/06/08 Vue.js