对于django的model,尤其是related field,我建议从model的本身含义出发,而不要从数据库的角度去看。

related_field仅仅是表示model之间的关系,至于数据库的实现,需要的时候再去了解。这样才能比较容易的理解django的model设计思想。

比如ForeignKey的含义,就是多对一的关系。这里并非字段的对应,而是model的对应。也就是说,有多个model对应一个model。所以ForeignKey在django中,就是表示model的含义,而非字段。

ManyToManyField的含义,也是指定多个model对应于多个model的关系。

先建立所需的model:

class Color(models.Model):name = models.CharField(max_length=10)def __str__(self)return self.nameclass Fruit(models.Model):name = models.CharField(max_length=10)price = models.IntegerField()color = models.ForeignKey(Color)def __str__(self)return self.nameclass Area(models.Model):province = models.CharField(max_length=10)fruits = models.ManyToManyField(Fruit)def __str__(self)return self.nameclass User(models.Model):name = models.CharField(max_length=10)fruits = models.ManyToManyField(Fruit, related_name='related_name', related_query_name='related_query_name')def __str__(self)return self.name

Fruit与Area是多对多的关系, 一个地区会生产多种水果,而一种水果也会被多个地区生产。

Fruit与User是多对多的关系,一个用户可以喜欢多种水果,而一种水果也会被多个用户喜欢。

Fruit与Color是多对一,一种水果相对有一种颜色。

插入数据:

首先向Color插入数据:

>>> color_red = Color(name='red')
>>> color_yellow = Color(name='yellow')
>>> color_red.save()
>>> color_yellow.save()
>>> color_green = Color(name='green')
>>> color_green.save()

然后向Fruit插入数据。注意color是Fruit的外键,所以添加时,需要指定color为Color的实例。

>>> apple = Fruit(name='apple', price=10, color=color_red)
>>> apple.save()
>>> orange = Fruit(name='orange', price=5, color=color_yellow)
>>> orange.save()
>>> watermelon = Fruit(name='watermelon', price=20, color=color_green)
>>> watermelon.save()

然后向Area添加数据。注意Area和Fruit是多对多的关系,必须先保存,然后在来指定两者的关系。

>>> shanghai = Area(province='shanghai')
>>> shanghai.save()
>>> guangzhou = Area(province='guangzhou')
>>> guangzhou.save()>>> shanghai.fruits.add(apple)
>>> apple.area_set.add(guangzhou)

关系的添加和删除是由ManyRelatedManager对象管理的。

它的获取方式与ManyToManyField的定义的位置有关。

如果在有ManyToManyField的model中,直接提取字段名就可以。

在没有ManyToManyField的model中, 使用related_name获取,如果没有默认为xxx_set, xxx为对应的model名。

向User添加数据,

>>> jack = User(name='jack')
>>> jack.save()
>>> jack.fruits.add(apple)
>>> orange.related_name.add(jack)>>> july = User(name='july')
>>> july.save()
>>> july.fruits.add(apple)

查询数据

查询有喜欢apple的user

>>> User.objects.filter(fruits__name='apple')
<User: jack>, <User: july>]

这里使用了双下划线, xxxx1__xxxx2。

xxxx1的获取,

分为两种情况

  1. ManyToManyField在model中

    直接获取其字段名

  2. ManyToManyField不在model中

a.  获取ManyToManyField的related_query_name属性。

b. 获取ManyToManyField的related_name属性。

c. 获取对应model名的小写格式。

xxxx2即为字段名。

查询有用户是jack的喜欢的水果

>>> Fruit.objects.filter(related_query_name__name='jack')
[<Fruit: apple>, <Fruit: orange>]
>>>
>>> User.objects.get(name='jack').fruits.all()
[<Fruit: apple>, <Fruit: orange>]

查询用户名是j开头的喜欢的水果

>>> Fruit.objects.filter(related_query_name__name__startswith='j')
[<Fruit: apple>, <Fruit: orange>, <Fruit: apple>]

这里指定了related_name和related_query_name的属性值,比较特殊,是为了更好的解释其作用。

一般来说,我习惯把related_name设为model的名字加上s, related_query_name设为model的名。

比如上面的User中fruits字段,

fruits = models.ManyToManyField(Fruit, related_name='users', related_query_name='user')

最后有一点注意到,如果一个model会有两个指向同一个model的外键。那么这两个外键必须指定related_name,并且还不能相同。举例来说:

class User(models.Model):name = models.CharField(max_length=20)def __str__(self):return self.nameclass Message(models.Model):content = models.CharField(max_length=200)sender = models.ForeignKey(User, related_name='send_messages')receiver = models.ForeignKey(User, related_name='receive_messages')def __str__(self):return self.content

写数据:

>>> names = ['Mary', 'Jim', 'Sam']
>>> for name in names:user = User(name=name)user.save()
>>> import itertools
>>> users = User.objects.all()
>>> for sender, receiver in itertools.permutations(users, 2):content = '%s-to-%s' % (sender.name, receiver.name)msg = Message(content=content, sender=sender, receiver=receiver)msg.save()

在上面代码中,实例化三个人Mary,Jim,Sam。并且都互相发送了短信。

>>> Mary = User.objects.get(name='Mary')# get messages which Mary sends
>>> Mary.send_messages.all()
[<Message: Mary-to-Jim>, <Message: Mary-to-Sam>]# get messages which Mary reveives
>>> Mary.receive_messages.all()
[<Message: Jim-to-Mary>, <Message: Sam-to-Mary>]

转载于:https://my.oschina.net/u/569730/blog/370536

django.relatedField-关联域相关推荐

  1. django 允许跨域请求

    django允许跨域请求配置 下载corsheader pip install django-cors-headers 修改setting.py中配置 在INSTALLED_APPS中增加corshe ...

  2. django允许跨域请求配置

    2019独角兽企业重金招聘Python工程师标准>>> django允许跨域请求配置 下载corsheader pip install django-cors-headers 修改s ...

  3. matlab广域保护分区算法,基于行波信息的广域后备保护关联域识别方法与流程

    本发明属于广域后备保护技术领域,具体涉及一种基于行波信息的广域后备保护关联域识别方法. 背景技术: 随着广域测量系统的发展,全网数据共享得以实现,在信息全景化的背景下,广域保护系统将电力系统继电保护由 ...

  4. 【django】关联查询

    一.关联查询 1.查询影⽚编号为2的所有⼈物信息 由⼀到多的访问语法: 对应的模型类对象.对应的模型类名⼩写_set f1=FilmInfo.objects.get(fid=2) f1.peoplei ...

  5. django解决跨域问题

    什么是跨域? 跨域:指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制 同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域 ...

  6. Django框架深入了解_05 (Django中的缓存、Django解决跨域流程(非简单请求,简单请求)、自动生成接口文档)(二)

    二.跨域: 回到顶部 跨域知识介绍: 点我以前博客 跨域解决方法:CORS:跨域资源共享 CORS请求分类(简单请求和非简单请求) 简单请求(simple request):只需要在头信息之中增加一个 ...

  7. Django框架深入了解_05 (Django中的缓存、Django解决跨域流程(非简单请求,简单请求)、自动生成接口文档)(一)

    阅读目录 一.Django中的缓存: 前戏: Django中的几种缓存方式: Django中的缓存应用: 二.跨域: 跨域知识介绍: CORS请求分类(简单请求和非简单请求) 示例: 三.自动生成接口 ...

  8. Python django解决跨域请求的问题

    解决方案 1.安装django-cors-headers pip3 install django-cors-headers 2.配置settings.py文件 INSTALLED_APPS = [.. ...

  9. django orm关联查询_Django ORM 聚合查询和分组查询实现详解

    models.py: from django.db import models # 出版社 class Publisher(models.Model): id = models.AutoField(p ...

  10. drf版本控制 和django缓存,跨域问题,

    drf版本控制 基于url的get传参方式 REST_FRAMEWORK={ # "DEFAULT_AUTHENTICATION_CLASSES":["app01.aut ...

最新文章

  1. iframe 有那些缺
  2. 数据结构-算法: 分配排序(基数分配排序法)
  3. 马斯克认为 AI 必超越并威胁人类,他宁愿搞脑机接口也不碰AI
  4. myqsl cluster error code 2310
  5. BZOJ#3252. 攻略
  6. php 方法参数传递,在PHP中将实例方法作为参数传递
  7. URLDecoder: Illegal hex characters in escape (%) pattern ...
  8. kotlin 16进制_Kotlin程序将八进制数转换为十进制数
  9. 华为鸿蒙系统明年8月份,华为鸿蒙系统明年上线,力争第五大操作系统,能否成功?...
  10. 微软中国:Morro可能将不进入中国市场
  11. (17)System Verilog枚举类型enum详解
  12. 创建私有 Gems 源
  13. react 动态修改路由_react动态路由以及获取动态路由
  14. 安装mysql-community-server报错缺少libaio依赖
  15. 【物联大师】之物联网智能网关
  16. 搭建无iDP证书的Xcode环境
  17. 云存储平台——Seafile搭建
  18. 网吧服务器多长时间维护,网吧服务器常用设置维护工具
  19. android+自定义dns解析,安卓手机玩dnsmasq 搭建自己的DNS服务器
  20. 错误代码:DNS_PROBE_FINISHED_NXDOMAIN解决办法

热门文章

  1. ld 无法找到项目符号 链接失败_【Linux】一步一步学Linux——ld命令(256)
  2. Codeforces 227E/226C Anniversary 斐波那契数列性质+矩阵快速幂
  3. matlab设置三维图等高线,MATLAB --三维图形等高线
  4. 函数input()讲解
  5. 关于调用360极速浏览器 2345浏览器的方法
  6. python编程 个人所得税计算器
  7. 苹果手机注册时显示链接服务器出现问题,苹果手机出现连接到服务器时出现问题是什么回事...
  8. 地月距离竟然如此遥远
  9. C语言编程练习 7.13个人围成一圈,从第1个人开始顺序报号1、2、3,凡报到3的人退出圈子。
  10. 整车控制器(VCU,vehicle Controller Unit)