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实现带错误处理功能的远程文件读取方法
Apr 29 Python
python导出chrome书签到markdown文件的实例代码
Dec 27 Python
Django后台获取前端post上传的文件方法
May 28 Python
python 构造三维全零数组的方法
Nov 12 Python
Python中xml和json格式相互转换操作示例
Dec 05 Python
python在回调函数中获取返回值的方法
Feb 22 Python
python快排算法详解
Mar 04 Python
Python3最长回文子串算法示例
Mar 04 Python
Python基础之条件控制操作示例【if语句】
Mar 23 Python
django框架使用方法详解
Jul 18 Python
Tensorflow 实现分批量读取数据
Jan 04 Python
python单例设计模式实现解析
Jan 07 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
smarty巧妙处理iframe中内容页的代码
2012/03/07 PHP
redis+php实现微博(三)微博列表功能详解
2019/09/23 PHP
用jquery生成二级菜单的实例代码
2013/06/24 Javascript
完美解决IE低版本不支持call与apply的问题
2013/12/05 Javascript
jQuery在ul中显示某个li索引号的方法
2015/03/17 Javascript
JS实现为排序好的字符串找出重复行的方法
2016/03/02 Javascript
JS键盘版计算器的制作方法
2016/12/03 Javascript
vue .sync修饰符的使用详解
2018/06/15 Javascript
js限制input只能输入有效的数字(第一个不能是小数点)
2018/09/28 Javascript
Bootstrap Paginator+PageHelper实现分页效果
2018/12/29 Javascript
玩转Koa之koa-router原理解析
2018/12/29 Javascript
vue使用codemirror的两种用法
2019/08/27 Javascript
JS如何实现手机端输入验证码效果
2020/05/13 Javascript
[53:13]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-GAMING
2014/05/22 DOTA
python单元测试unittest实例详解
2015/05/11 Python
Python脚本处理空格的方法
2016/08/08 Python
python访问抓取网页常用命令总结
2017/04/11 Python
Mac在python3环境下安装virtualwrapper遇到的问题及解决方法
2019/07/09 Python
如何基于pythonnet调用halcon脚本
2020/01/20 Python
Django如何使用jwt获取用户信息
2020/04/21 Python
详解Django配置JWT认证方式
2020/05/09 Python
Python使用matplotlib绘制圆形代码实例
2020/05/27 Python
DRF框架API版本管理实现方法解析
2020/08/21 Python
python多线程和多进程关系详解
2020/12/14 Python
CSS3动画之流彩文字效果+图片模糊效果+边框伸展效果实现代码合集
2017/08/18 HTML / CSS
NUK奶瓶美国官网:NUK美国
2016/09/26 全球购物
Stubhub英国:购买体育、演唱会和剧院门票
2018/06/10 全球购物
服务中心夜班服务员岗位职责
2013/11/27 职场文书
亲子拓展活动方案
2014/02/20 职场文书
敬业奉献模范事迹材料
2014/12/24 职场文书
计划生育汇报材料
2014/12/26 职场文书
泰山导游词
2015/02/02 职场文书
肖申克救赎观后感
2015/06/02 职场文书
详解MindSpore自定义模型损失函数
2021/06/30 Python
Python anaconda安装库命令详解
2021/10/16 Python
Python中的程序流程控制语句
2022/02/24 Python