django的ManyToManyField

使用場景: 多對多的關係可使用ManyToManyField,其實也能夠直接本身手動寫一個關聯表,可是不若有ManyToManyField字段的話查詢會方便不少。python

以學校爲例,這裏有兩個表,一個是專業表,一個是學校表,學校應該包含專業,並且應該是多對多的關係,  以下是學校表:django

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爲一對多的外鍵,覺得學校只會有一個位置信息(不考慮分校。。), 熱門和類別都是多對多的關係,專業也是多對多的關係,spa

hot 和category爲兩個特別簡單的ManyToManyField。 major由於須要在關係上有自定義屬性,因此指定了關係表SchoolMajor:code

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字段。blog

 

以上爲基礎的使用方式,詳細的能夠查看django官方文檔:https://docs.djangoproject.com/en/1.9/topics/db/examples/many_to_many/文檔

或者我找到的介紹的挺詳細的博客:http://luozhaoyu.iteye.com/blog/1510635get

 

ManyToMany的查詢

如上例子,查詢某個學校下全部專業:school.major.all()便可。 博客

查詢包含id爲1的專業的全部學校,能夠直接經過School.objects.filter(major_id=1), 也能夠經過major反查,先獲取到id爲1的major,而後major.school_major_set.all() 便可。it

有些狀況下咱們須要查詢出來既有id爲1專業的學校 也有id爲2專業的學校,這裏就可使用filter鏈:io

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

相關文章
相關標籤/搜索