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生成IP段的方法
Jul 07 Python
python模仿网页版微信发送消息功能
Feb 24 Python
深入理解Django的中间件middleware
Mar 14 Python
Python OpenCV处理图像之图像像素点操作
Jul 10 Python
python获取txt文件词向量过程详解
Jul 05 Python
Python数据类型之列表和元组的方法实例详解
Jul 08 Python
python实现在一个画布上画多个子图
Jan 19 Python
Jupyter Notebook打开任意文件夹操作
Apr 14 Python
Keras使用ImageNet上预训练的模型方式
May 23 Python
Python爬虫过程解析之多线程获取小米应用商店数据
Nov 14 Python
Python机器学习算法之决策树算法的实现与优缺点
May 13 Python
如何用python清洗文件中的数据
Jun 18 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
DIY一个适配电脑声卡的动圈话筒放大器
2021/03/02 无线电
PHP 一个随机字符串生成代码
2010/05/26 PHP
使用PHP遍历文件夹与子目录的函数代码
2011/09/26 PHP
php广告加载类用法实例
2014/09/23 PHP
Zend Framework数据库操作方法实例总结
2016/12/11 PHP
PHP PDO数据库操作预处理与注意事项
2019/03/16 PHP
Expandable "Detail" Table Rows
2007/08/29 Javascript
javascript 浏览器判断 绑定事件 arguments 转换数组 数组遍历
2009/07/06 Javascript
jquery 注意事项与常用语法小结
2010/06/07 Javascript
使用js解决由border属性引起的div宽度问题
2013/11/26 Javascript
jquery中html、val与text三者属性取值的联系与区别介绍
2013/12/29 Javascript
js实现按Ctrl+Enter发送效果
2014/09/18 Javascript
jQuery.Highcharts.js绘制柱状图饼状图曲线图
2015/03/14 Javascript
Javascript HTML5 Canvas实现的一个画板
2020/04/12 Javascript
vue 1.x 交互实现仿百度下拉列表示例
2017/10/21 Javascript
elemetUi 组件--el-upload实现上传Excel文件的实例
2017/10/27 Javascript
极简主义法编写JavaScript类
2017/11/02 Javascript
vue.js给动态绑定的radio列表做批量编辑的方法
2018/02/28 Javascript
vue中@change兼容问题详解
2019/10/25 Javascript
VUE和Antv G6实现在线拓扑图编辑操作
2020/10/28 Javascript
[47:06]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第一局
2016/03/05 DOTA
[03:24]CDEC.Y赛前采访 努力备战2016国际邀请赛中国区预选赛
2016/06/25 DOTA
[43:18]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
Python建立Map写Excel表实例解析
2018/01/17 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
2020/02/24 Python
CSS3 函数技巧 用css 实现js实现的事情(clac Counters Tooltip)
2017/08/15 HTML / CSS
初二政治教学反思
2014/01/12 职场文书
乡镇纠风工作实施方案
2014/03/22 职场文书
2014优秀大学生简历自我评价
2014/09/15 职场文书
青少年法制教育心得体会
2016/01/14 职场文书
2016年敬老月活动总结
2016/04/05 职场文书
网络新闻该怎么写?这些写作技巧你都知道吗?
2019/08/26 职场文书
python自然语言处理之字典树知识总结
2021/04/25 Python
如何理解python接口自动化之logging日志模块
2021/06/15 Python
详解Redis在SpringBoot工程中的综合应用
2021/10/16 Redis
Anaconda安装pytorch和paddle的方法步骤
2022/04/03 Python