文档章节

django的ManyToManyField

子夜闻雪
 子夜闻雪
发布于 2015/12/11 11:19
字数 606
阅读 2171
收藏 1

使用场景: 多对多的关系可以使用ManyToManyField,其实也可以直接自己手动写一个关联表,但是不如有ManyToManyField字段的话查询会方便很多。

以学校为例,这里有两个表,一个是专业表,一个是学校表,学校应该包含专业,而且应该是多对多的关系,  如下是学校表:

class School(MyModel):
    name = models.CharField(_("校名"), max_length=200, help_text="最多200字")
    intro = models.CharField(_('简介'), max_length=5000,null=True, blank=True, help_text="最多5000字")
    base_info = models.CharField(_('基本信息'), max_length=5000, null=True, blank=True, help_text="最多5000字")
    address = models.ForeignKey(Area, verbose_name=_('所属位置'), null=True, blank=True)
    hot = models.ManyToManyField(Hot, verbose_name=_('热门'), null=True, blank=True, related_name="school_hot_set")
    category = models.ManyToManyField(Category, verbose_name=_('类别'), null=True, blank=True,
                                      related_name="school_category_set")
    major = models.ManyToManyField(Major, verbose_name=_('专业'), null=True ,blank=True,
                                   related_name="school_major_set", through='SchoolMajor')
 

这里能看到有多个外键, address为一对多的外键,以为学校只会有一个位置信息(不考虑分校。。), 热门和类别都是多对多的关系,专业也是多对多的关系,

hot 和category为两个特别简单的ManyToManyField。 major因为需要在关系上有自定义属性,所以指定了关系表SchoolMajor:

class SchoolMajor(MyModel):
    major = models.ForeignKey(Major, verbose_name=_('专业'))
    school = models.ForeignKey(School, verbose_name=_('学校'))
    type = models.IntegerField(_('类型'), choices=((0, '本科'), (1, '研究生'), (2, '本硕')))
    create_time = models.DateTimeField(_('创建时间'), auto_now_add=True)

看到除了两个外键外,增加了type和create_time字段。

 

以上为基础的使用方式,详细的可以查看django官方文档:https://docs.djangoproject.com/en/1.9/topics/db/examples/many_to_many/

或者我找到的介绍的挺详细的博客:http://luozhaoyu.iteye.com/blog/1510635

 

ManyToMany的查询

如上例子,查询某个学校下所有专业:school.major.all()即可。 

查询包含id为1的专业的所有学校,可以直接通过School.objects.filter(major_id=1), 也可以通过major反查,先获取到id为1的major,然后major.school_major_set.all() 即可。

有些情况下我们需要查询出来既有id为1专业的学校 也有id为2专业的学校,这里就可以使用filter链:

School.objects.filter(major_id=1).filter(major_id=2)

如果想查询出只有两个专业的学校:

School.objects.annotate(count=Count("major")).filter(count=2)

结合上面两个,查询出只有专业1和专业2的学校:

School.objects.annotate(count=Count("major"))..filter(major_id=1).filter(major_id=2).filter(count=2)

参考资料:http://stackoverflow.com/questions/5301996/how-to-do-many-to-many-django-query-to-find-book-with-2-given-authors

 

 

 

 

© 著作权归作者所有

子夜闻雪
粉丝 3
博文 37
码字总数 16415
作品 0
海淀
程序员
私信 提问
Django关于模型详解

简介 模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。 基础: 每个模型都是django.db.models.Model 的一个Python 子...

楠木楠
2016/09/25
400
0
我的网站搭建 (第十九天) 标签功能

在逛开源中国社区的时候,发现每一篇博客下面都有一行文章的标签,大概就是文章中的代码类型以及使用到的模块之类的。如下图,我的开源中国社区地址是:https://my.oschina.net/zhenfei。 转...

代码打碟手
2018/10/10
33
0
Django 操作Mysql连表操作

多对多 ManyToManyField models.py 生成的用户组表 生成的用户信息表 注意:如上图所示,Django 定义 的 ManyToManyField 字段并没有在 UserGroup 表中生成 UserGroup 跨表取值 u = models.U...

明月知心
2016/12/21
40
0
python-django中models的Meta内部类设置

  简介      Django模型类的Meta是一个内部类,它用于定义一些Django模型类的行为特性。      abstract   这个属性是定义当前的模型是不是一个抽象类。所谓抽象类是不会对应数据...

运维菜
2018/02/03
0
0
django values(*field) values_list() 使用

这个方法返回的是ValuesQuerySet,是QuerySet 的子类,也就是说,你可以用QuerySet里的方法。 需要注意的是,返回的不是list,不要直接当list来用了。对ValuesQuerySet遍历,每一个元素是“字...

jacked
2015/10/14
4K
2

没有更多内容

加载失败,请刷新页面

加载更多

经典系统设计面试题解析:如何设计TinyURL(二)

原文链接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
今天
7
0
使用logstash同步MySQL数据到ES

概述   在生成业务常有将MySQL数据同步到ES的需求,如果需要很高的定制化,往往需要开发同步程序用于处理数据。但没有特殊业务需求,官方提供的logstash就很有优势了。   在使用logstas...

zxiaofan666
今天
10
0
X-MSG-IM-分布式信令跟踪能力

经过一周多的鏖战, X-MSG-IM的分布式信令跟踪能力已基本具备, 特点是: 实时. 只有要RX/TX就会实时产生信令跟踪事件, 先入kafka, 再入influxdb待查. 同时提供实时sub/pub接口. 完备. 可以完整...

dev5
今天
7
0
OpenJDK之CyclicBarrier

OpenJDK8,本人看的是openJDK。以前就看过,只是经常忘记,所以记录下 图1 CyclicBarrier是Doug Lea在JDK1.5中引入的,作用就不详细描述了,主要有如下俩个方法使用: await()方法,如果当前线...

克虏伯
今天
8
0
实战项目-学成在线(八)

在前后端分离架构中,服务层被拆分成了很多的微服务,微服务的信息如何管理?Spring Cloud中提供服务注册中心来管理微服务信息。 注册中心作用: 1、微服务数量众多,要进行远程调用就需要知...

lianbang_W
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部