Chapter 14 Advanced Django-model (mediation model, query optimization, extra, overall insertion)

Django-model advanced (mediation model, query optimization, extra, overall insertion)

Read the content (Content)

mediation model

When dealing with simple many-to-many relationships like matching pizza and topping, use the standard ManyToManyField   . However, sometimes you may need to correlate data to a relationship between two models.

For example, there is an application that records the musical groups a musician belongs to. We can use a ManyToManyField  to represent a many-to-many relationship between groups and members. However, sometimes you may want to know more details about membership, such as when members joined the group.

For these cases, Django allows you to specify an intermediary model to define a many-to-many relationship. You can put other fields inside the mediation model. The source model's ManyToManyField  field will use the through  parameter to point to the intermediary model. For the music group example above, the code is as follows:

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)

Now that you've set up the ManyToManyField to use the mediation model ( Membership  in this case ), you'll start creating the many-to-many relationship. All you have to do is create an instance of the mediation model:

>>> 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>]

Unlike normal many-to-many fields, you cannot use addcreate and assignment statements (eg beatles.members  [...] ) to create relationships:

# THIS WILL NOT WORK
>>> beatles.members.add(john)
# NEITHER WILL THIS
>>> beatles.members.create(name="George Harrison")
# AND NEITHER WILL THIS
>>> beatles.members = [john, paul, ringo, george]

Why can't this be done? This is because you can't just create  an association between  Person and  Group , you also specify all the information you need in the Membership model; simple add , create ,  and assignment statements can't do that. So they cannot be used in many-to-many relationships using the mediation model. At this point, the only way is to create an instance of the mediation model.

 The remove() method is disabled for the same reason. But the clear()  method is available. It can clear all the many-to-many relationships of an instance

>>> # Beatles have broken up
>>> beatles.members.clear()
>>> # Note that this deletes the intermediate model instances
>>> Membership.objects.all()
[]

Query optimization

extra

overall insertion

  

  

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324634953&siteId=291194637