美文网首页django
django-model外键关系之多对多

django-model外键关系之多对多

作者: 陆_志东 | 来源:发表于2018-08-22 21:53 被阅读159次

    多对多

    ManyToManyField用来定义多对多关系
    多对多在哪个模型中设置ManyToManyField并不重要,在两个模型中任选一个即可 —— 不要两个模型都设置。

    在本例中,一篇文章可以在多个发布对象中发布,并且发布具有多个文章对象:

    from django.db import models
    
    class Publication(models.Model):
        title = models.CharField(max_length=30)
    
        def __str__(self):              # __unicode__ on Python 2
            return self.title
    
        class Meta:
            ordering = ('title',)
    
    class Article(models.Model):
        headline = models.CharField(max_length=100)
        publications = models.ManyToManyField(Publication)
    
        def __str__(self):              # __unicode__ on Python 2
            return self.headline
    
        class Meta:
            ordering = ('headline',)
    

    多对多的使用和绑定

    # Create a couple of Publications:
    >>> p1 = Publication(title='The Python Journal')
    >>> p1.save()
    >>> p2 = Publication(title='Science News')
    >>> p2.save()
    >>> p3 = Publication(title='Science Weekly')
    >>> p3.save()
    #Create an Article:
    >>> a1 = Article(headline='Django lets you build Web apps easily')
    # You can’t associate it with a Publication until it’s been saved:
    >>> a1.publications.add(p1)
    Traceback (most recent call last):
    ...
    ValueError: 'Article' instance needs to have a primary key value before a many-to-many relationship can be used.
    
    #Save it!
    >>> a1.save()
    >>> a1.publications.add(p1)
    >>> a2 = Article(headline='NASA uses Python')
    >>> a2.save()
    >>> a2.publications.add(p1, p2)
    >>> a2.publications.add(p3)
    #可以添加多次,也不会报错
    >>> a2.publications.add(p3)
    
    # 但是如果添加绑定的不属于外键关系就会出错
    >>> a2.publications.add(a1)
    Traceback (most recent call last):
    ...
    TypeError: 'Publication' instance expected
    
    #使用关联对象
    >>> a1.publications.all()
    [<Publication: The Python Journal>]
    >>> a2.publications.all()
    [<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]
    >>> p2.article_set.all()
    [<Article: NASA uses Python>]
    >>> p1.article_set.all()
    [<Article: Django lets you build Web apps easily>, <Article: NASA uses Python>]
    >>> Publication.objects.get(id=4).article_set.all()
    [<Article: NASA uses Python>]
    

    有中间人模式的多对多关系

    from django.db import models
    
    class Person(models.Model):
        name = models.CharField(max_length=128)
    
        def __str__(self):              # __unicode__ on Python 2
            return self.name
    
    class Group(models.Model):
        name = models.CharField(max_length=128)
        members = models.ManyToManyField(Person, through='Membership')
    
        def __str__(self):              # __unicode__ on Python 2
            return self.name
    
    class Membership(models.Model):
        person = models.ForeignKey(Person)
        group = models.ForeignKey(Group)
        date_joined = models.DateField()
        invite_reason = models.CharField(max_length=64)
    

    多对多中间人模式的创建和绑定

    #带有中间人的模式不能使用add和create语句创建
    #只能先创建对象,然后利用中间人进行绑定,创建对象的时候是不赋值外键字段的,利用中间人绑定之后,会自动创建外键
    >>> ringo = Person.objects.create(name="Ringo Starr")
    >>> paul = Person.objects.create(name="Paul McCartney")
    >>> beatles = Group.objects.create(name="The Beatles")
    >>> m1 = Membership(person=ringo, group=beatles,
    ...     date_joined=date(1962, 8, 16),
    ...     invite_reason="Needed a new drummer.")
    >>> m1.save()
    >>> beatles.members.all()
    [<Person: Ringo Starr>]
    >>> ringo.group_set.all()
    [<Group: The Beatles>]
    >>> m2 = Membership.objects.create(person=paul, group=beatles,
    ...     date_joined=date(1960, 8, 1),
    ...     invite_reason="Wanted to form a band.")
    >>> beatles.members.all()
    [<Person: Ringo Starr>, <Person: Paul McCartney>]
    

    相关文章

      网友评论

        本文标题:django-model外键关系之多对多

        本文链接:https://www.haomeiwen.com/subject/jwruiftx.html