django的ManyToManyField

使用场景: 多对多的关系可以使用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

 

 

 

 

转载于:https://my.oschina.net/u/2299936/blog/542711

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值