Django many-to-many relationships, django many-to-Relationship

Source: Internet
Author: User

Django many-to-many relationships, django many-to-Relationship

Django 1, 1.7


Use ManyToManyFiled to define multiple-to-multiple relationships.

In this example, the Article can be published on multiple publications, and the Publication can have multiple Article objects.


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



The following is an example of using Python APIs. Note: If you use an intermediate model for many-to-many relationships, some relational manager methods cannot be used, so some of these examples cannot work under this model.

Create several publications:


>>> P1 = Publication (title = 'the Python Journal ')

>>> P1.save ()

>>> P2 = Publication (title = 'science News ')

>>> P2.save ()

>>> P3 = Publication (title = 'science wekkly ')


Create an article:

>>> A1 = Article (headline = 'django lets you build web apps easily ')

Before saving it, it cannot be associated with a Publication.


>>> A1.publications. add (p1)

...

ValueError: 'Article' instance needs to have a primary key value before a failed-to-assign relationship can be used.


Save

>>> A1.save ()

Associate Article with Publication:

>>> A1.publications. add (p1)


Create another Article and set it to appear in two Publications:

>>> A2 = Article (headline = 'nasa uses python ')

>>> A2.save ()

>>> A2.publications. add (p1, p2)

>>> A2.publications. add (p3)

The 2nd add operation is correct:


>>> A2.publications. add (p3)


Adding an error type object produces a TypeError:

>>> A2.publictaions. add (a1)

Traceback (most recent call last ):

...

TypeError: 'publication' instance already ted


Use create () to create a Publications and add it to an article:

>>> New_publication = a2.publications. create (title = 'highlights for Children ')


Article objects can access their associated Publication objects:

>>> A1.publications. all ()

[<Publication: HIghlights for Children>,...]


>>> A2.publications. all ()

[<Publication: Highlights for Children>, <Publication: Science News>,...]


Publication objects can access their associated Article objects:

>>> P2.article _ set. all ()

[<Article: NASA uses Python>]

>>> P1.article _ set. all ()

[<Article: Django lets you build Web app easyily>, <Article: NASA uses Python>]

>>> Publication. objects. get (id = 4). article_set.all ()

[<Article: NASA uses Python>]


You can use cross-link query to obtain multi-to-Multi-link queries:


>>> Article. objects. filter (publications _ id = 1)

[<Article: Django lets you build Web app easyily>, <Article: NASA uses Python>]


>>> Article. objects. filter (publications _ pk = 1)

[<Article: Django lets you build Web app easyily>, <Article: NASA uses Python>]


>>> Article. objects. filter (publications = 1 ):

[<Article: Django lets you build Web app easyily>, <Article: NASA uses Python>]


>>> Article. objects. filter (publications = p1)

[<Article: Django lets you build Web app easyily>, <Article: NASA uses Python>]


>>> Article. objects. filter (publications _ title _ startwith = 'science ')

[<Article: NASA uses Python>, <Article: NASA uses Python>]


>>> Article. objects. filter (publications _ title _ startwith = 'science '). distinct ()

[<Article: NASA uses Python>]


The count () function also uses distinct ():

>>> Article. objects. filter (publications _ title _ startwith = 'science '). count ()

2

>>> Article. objects. filter (publications _ title _ startwith = 'science '). distinct (). count ()

1


>>> Article. objects. filter (publications _ in = [1, 2]). distinct ()

[<Article: Django lets you build Web app easyily>, <Article: NASA uses Python>]

>>> Article. objects. filter (publications _ in = [p1, p2]). distinct ()

[<Article: Django lets you build Web app easyily>, <Article: NASA uses Python>]


Reverse m2m query is also supported (for example, starting from a table without the ManyToManyField field ):

>>> Publication. objects. filter (id = 1)

[<Publication: The Python Journal>]

>>> Publication. objects. filter (pk = 1)

[<Publication: The Python Journal>]

>>> Publication. objects. filter (article _ headline _ startwith = 'nasa ')

[<Publication: Highlights for Children>, <Publication: Science News>,...]

>>> Publication. objects. filter (article _ id = 1)

[<Publication: The Python Journal>]

>>> Publication. objects. filter (article _ pk = 1)

[<Publication: The Python Journal>]

>>> Publication. objects. filter (article = 1)

[<Publication: The Python Journal>]

>>> Publication. objects. filter (article = a1)

[<Publication: The Python Journal>]

Publication. objects. filter (article _ in = [1, 2]). distinct ()

[<Publication: Highlights for Children>, <Publication: Science News>,...]

>>> Publication. objects. filter (article _ in = [a1, a2]). distinct ()

[<Publication: Highlights for Children>, <Publication: Science News>,...]


Excluding an associated project will work as expected (although the SQL used is a little complicated ):

>>> Article. objects. exclude (publications = p2)

[<Article: Django lets you build Web apps easily>]


If we delete Publication, its Article will not be able to access it:

>>> P1.delete ()

>>> Publication. objects. all ()

[<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly> ']

>>> A1 = Article. objects. get (pk = 1)

>>> A1.publications. all ()

[]


If we delete an Article, its Publications will not be able to access it:

>>> A2.delete ()

>>> Article. objects. all ()

[<Artilce: Django lets you bulid Web apps easily>]

>>> P2.article _ set. all ()

[]


Add through the other end of m2m:

>>> A4 = Article (headline = 'nasa finds intelligent lif on global ')

>>> A4.save ()

>>> P2.article _ set. add (a4)

>>> P2.article _ set. all ()

[<Article: NASA finds intelligent lif on Earth>]

>>> A4.publications. all ()

[<Publication: Science News>]


Add using keywords on the other end:

>>> New_article = p2.article _ set. create (headline = 'Oxygen-free diet works wonders ')

>>> P2.article _ set. all ()

[<Article: NASA finds intelligent lif on Earth>, <Article: Oxygen-free diet works wonders>]

>>> A5 = p2.article _ set. all () [1]

>>> A5.publications. all ()

[<Publication: Science News>]


Remove Publication from 1 Article:

>>> A4.publications. remove (p2)

>>> P2.article _ set. all ()

[<Article: Oxygen-free diet works wonders>]

>>> A4.publications. all ()

[]


From the other end:


>>> P2.article _ set. remove (a5)

>>> P2.article _ set. all ()

[]

>>> A5.publications. all ()

[]


You can assign values to a relational set. The assign value operation clears any existing set members:

>>> A4.publications. all ()

[<Publication: Science News>]

>>> A4.publications = [p3]

>>> A4.publications. all ()

[<Publication: Science Weekly>]


Link set can be cleared:

>>> P2.article _ set. clear ()

>>> P2.article _ set. all ()

[]


You can also clear from the other end:

>>> P2.article _ set. add (a4, a5)

>>> P2.article _ set. all ()

[<Article: NASA finds intelligent lif on Earth>, <Article: Oxygen-free diet works wonders>]

>>> A4.publications. clear ()

>>> A4.publications. all ()

[]

>>> P2.article _ set. all ()

[<Article: Oxygen-free diet works wonders>]


Re-create the articles and Publications we have deleted:

>>> P1 = Publication (title = 'the Python Journal ')

>>> P1.save ()

>>> A2 = Article (headline = 'nasa uses python ')

>>> A2.save ()

>>> A2.publications. add (p1, p2, p3)


Batch delete some Publications-reference deleted publications are also deleted:

>>> Publication. objects. filter (title _ startwith = 'science '). delete ()

>>> Publication. objects. all ()

[<Publication: Highlights for Children>, <Publication: The Python Journal>]

>>> Article. objects. all ()

[<Article: Django lets you build Web apps easily>,...]

>>> A2.publications. all ()

[<Publication: The Python Journal>]


Batch delete some articles-objects referenced and deleted are also deleted:

>>> Q = Article. objects. filter (headline _ startwith = 'django ')

>>> Print (q)

[<Article: Django lets you build Web apps easily>]

>>> Q. delete ()


After delete () is called, The QeruySet cache needs to be cleared, and the music object will also be deleted:

>>> Print (q)

[]

>>> P1.article _ set. all ()

[<Article: NASA uses Python>]


The alternative to calling clear () is to assign a null set:

>>> P1.article _ set = []

>>> P1.article _ set. all ()


>>> A2.publications = [p1, new_publication]

>>> A2.publications. all ()

[<Publication: Highlights for Children>, <Publication: The Python Journal>]

>>> A2.publications = []

>>> A2.publications. all ()

[]




Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.