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环境下安装使用异步任务队列包Celery的基础教程
May 07 Python
python cs架构实现简单文件传输
Mar 20 Python
余弦相似性计算及python代码实现过程解析
Sep 18 Python
Python脚本导出为exe程序的方法
Mar 25 Python
使用Jupyter notebooks上传文件夹或大量数据到服务器
Apr 14 Python
解决python虚拟环境切换无效的问题
Apr 30 Python
python 异步async库的使用说明
May 04 Python
Python实现一个简单的毕业生信息管理系统的示例代码
Jun 08 Python
Python3爬虫中Ajax的用法
Jul 10 Python
Python远程方法调用实现过程解析
Jul 28 Python
解决python便携版无法直接运行py文件的问题
Sep 01 Python
Numpy实现卷积神经网络(CNN)的示例
Oct 09 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
基于asp+ajax和数据库驱动的二级联动菜单
2010/05/06 PHP
php 备份数据库代码(生成word,excel,json,xml,sql)
2013/06/23 PHP
PHP函数超时处理方法
2016/02/14 PHP
详解Laravel视图间共享数据与视图Composer
2016/08/04 PHP
基于CI(CodeIgniter)框架实现购物车功能的方法
2018/04/09 PHP
php设计模式之观察者模式实例详解【星际争霸游戏案例】
2020/03/30 PHP
javascript下IE与FF兼容函数收集
2008/09/17 Javascript
用js统计用户下载网页所需时间的脚本
2008/10/15 Javascript
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
2012/06/22 Javascript
开发 Internet Explorer 右键功能表(ContextMenu)
2013/07/03 Javascript
getJSON调用后台json数据时函数被调用两次的原因猜想
2013/09/29 Javascript
div浮层,滚动条移动,位置保持不变的4种方法汇总
2013/12/11 Javascript
AngularJS HTML编译器介绍
2014/12/06 Javascript
JavaScript中几种排序算法的简单实现
2015/07/29 Javascript
浅析Javascript匿名函数与自执行函数
2016/02/06 Javascript
Javascript技术栈中的四种依赖注入小结
2016/02/27 Javascript
javascript jquery对form元素的常见操作详解
2016/06/12 Javascript
JS获取当前使用的浏览器名字以及版本号实现方法
2016/08/19 Javascript
JS实现图片预览的两种方式
2017/06/27 Javascript
jquery拖拽自动排序插件使用方法详解
2020/07/20 jQuery
[15:15]教你分分钟做大人:狙击手
2014/10/30 DOTA
批处理与python代码混合编程的方法
2016/05/19 Python
python矩阵的转置和逆转实例
2018/12/12 Python
python利用跳板机ssh远程连接redis的方法
2019/02/19 Python
AmazeUI 平滑滚动效果的示例代码
2020/08/20 HTML / CSS
英国团购网站:Groupon英国
2017/11/28 全球购物
Opodo英国旅游网站:预订廉价航班、酒店和汽车租赁
2018/07/14 全球购物
通往英国高街的商店橱窗:Down Your High Street
2020/07/19 全球购物
什么是事务?为什么需要事务?
2012/01/09 面试题
初中生操行评语大全
2014/04/24 职场文书
大班幼儿评语大全
2014/04/30 职场文书
地球物理学专业推荐信
2014/09/08 职场文书
介绍信模板
2015/01/31 职场文书
终止劳动合同通知书
2015/04/16 职场文书
2015年妇幼卫生工作总结
2015/05/23 职场文书
婚礼上证婚人致辞
2015/07/28 职场文书