Django 模型层访问关联对象 README

概述

本来是打算写Cheat Sheet的,但是又加入一点知识讲解,所以称作README好了。
本文假设你已经掌握对象关系相关的基础知识。

正向访问与反向访问

首先必需要明白的是正向访问和反向访问的概念,彻底明白后,在访问关联对象时就不会蒙圈了。

假设在模型A中定义了关系字段指向了模型B。

class A(models.Model):
    b = models.ManyToManyField(to='B')

那么A访问B就是正向访问,B访问A就是反向访问

需求模拟

假设我们要写一个企业内部的资产管理系统,每个应用我们用Node来表示,一个应用节点可能涉及很多信息,所以增加一个NodeExtension模型用来记录应用的扩展信息(例如描述、负责人、部门等信息);同一个应用,公司为了区分开发环境配置了不同的域名例如ehr、preehr、testehr;每个应用节点的负责人可能会有多个,每个负责人也可能同时负责多个应用。

Node表:用来表示应用节点,
NodeExtension表,用来表示应用节点的扩展信息,与Node表是一对一的关系,
Domain表:用来表示域名,与Node表是多对一的关系,
Owner表:用来表示负责人,与NodeExtension表是多对多的关系。

一对一

在Django中使用OneToOneField来表示一个一对一的关系。

class Node(models.Model):
  pass
class NodeExtension(models.Model):
    node = models.OneToOneField(to="Node", on_delete=models.CASCADE, null=True)

在这里插入图片描述

查询

在访问一对一的关联对象时,可以当作普通的字段(非关联的对象)对待。

正向访问

NodeExtension实例访问Node字段,使用声明的字段名

NODE_EXTENSION.node
反向访问

Node实例访问NodeExtension字段,使用对方表名(全部小写)

NODE.nodeextension

多对一

在Django中使用ForeignKey来表示多对一的关系,且只能在多的那一方进行使用

class Domain(models.Model):
    node = models.ForeignKey(to="Node", on_delete=models.SET_NULL, null=True, blank=True)

在这里插入图片描述

查询

正向访问

Domian实例访问Node字段,使用定义的字段名

DOMAIN.node
反向访问

Node实例访问Domain字段,使用对方表名(全部小写) +_set【重要】

NODE.domain_set.all()

增加

正向访问
DOMAIN.node = NODE
反向访问
NODE.domain_set.add(DOMAIN)
NODE.domain_set.set(DOMAIN_LIST)

删除

正向访问
DOMAIN.node = None
反向访问
NODE.domain_set.remove(DOMAIN)
NODE.domain_set.clear()

多对多

在Django中使用ManyToManyField来表示一个多对多的关系。

class Owner(models.Model):
    pass
class NodeExtension(models.Model):
    owners = models.ManyToManyField(to='Owner')

在这里插入图片描述

查询

正向访问

NodeExtension实例访问Owner字段,使用定义的字段名

NODE_EXTENSION.owners.all()
反向访问

Owner实例访问NodeExtension字段,使用对方表名(全部小写) +_set【重要】

OWNER.nodeextension_set.all()

增加-单条

反向访问
OWNER.nodeextension_set.add()
正向访问
NODE_EXTENSION.owners.add()

增加-集合

反向访问
OWNER.nodeextension_set.set(NODE_EXTENSION_LIST)
正向访问
NODE_EXTENSION.owners.set(OWNER_LIST)

删除-单条

反向访问
OWNER.nodeextension_set.remove(NODE_EXTENSION)
正向访问
NODE_EXTENSION.owners.remove(OWNER)

删除-全部

反向访问
OWNER.nodeextension_set.clear()
正向访问
NODE_EXTENSION.owners.clear()

操作方法 Cheat Sheet

将模型对象实例加入关联对象的集合中。

add(obj)
add(obj1, obj2, ...)

从关联对象的集合中删除指定的模型对象实例。

remove(obj)
remove(obj1, obj2, ...)

从关联对象集合删除所有对象。

clear()

用模型对象实例的集合替换关联对象的集合。

set(objs)

自定义反向访问的字段名

在关系字段中使用related_name参数来指定反向访问的字段名

class Domain(models.Model):
    name = models.CharField(max_length=32)
    node = models.ForeignKey(to='Node', on_delete=models.SET_NULL,
                             null=True, blank=True, related_name='domains')

正向访问

DOMAIN.node

反向访问

NDOE.domains

官方文档

https://docs.djangoproject.com/zh-hans/3.2/ref/models/relations/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值