Many to many intermediate tables
Default middle table
adopt through Custom middle table
Many to many intermediate tablesWe all know that for ManyToMany Field ,Django The third middle table is used . Through this third table , To relate ManyToMany Both sides of . Let's follow a specific example , Explain the use of the middle table in detail .
Default middle tableclass Person(models.Model): name = models.CharField(max_length=128) def __str__(self): return self.nameclass Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person) def __str__(self): return self.name
stay Group In the model , adopt members Field , With ManyToMany Ways and Person The model establishes the relationship .
Let's see , What does the middle watch look like :
First of all, there is a column id, This is a Django Default added , There's nothing to say . And then there was Group and Person Of id Column , This is by default ,Django How to associate two tables . If you want to set the associated columns , have access to to_field Parameters .
It can be seen in the middle table , It's not about saving data from both tables , But through id Mapping the relationship of .
adopt through Custom middle tableGeneral situation , Ordinary many to many is enough , You don't have to create a third relationship table yourself . But some situations can be a little more complicated , For example, if you want to save the time when someone joins a group ? Why do you want to save it ?
Django Provides a through Parameters , Used to specify the intermediate model , You can group similar time , Other fields such as invitation reason are placed in this intermediate model . Examples are as follows :
modle:
from django.db import modelsclass Person(models.Model): name = models.CharField(max_length=128) def __str__(self): return self.nameclass Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership') def __str__(self): return self.nameclass Membership(models.Model): person = models.ForeignKey(Person, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) date_joined = models.DateField() # Group time invite_reason = models.CharField(max_length=64) # The reason for the invitation
view:
class PersonViews(ModelViewSet): queryset = Person.objects.filter() serializer_class = PersonSerializersclass GroupViews(ModelViewSet): queryset = Group.objects.filter() serializer_class = GroupSerializersclass MembershipViews(ModelViewSet): queryset = Membership.objects.filter() serializer_class = MembershipSerializers
serializer:
from .models import Person, Group, Membershipclass MembershipSerializers(serializers.ModelSerializer): class Meta: model = Membership fields = '__all__'class PersonSerializers(serializers.ModelSerializer): class Meta: model = Person fields = '__all__'class GroupSerializers(serializers.ModelSerializer): def to_representation(self, instance): representation = super(GroupSerializers, self).to_representation(instance) representation['members'] = [] for i in PersonSerializers(instance.members, many=True).data: reason = MembershipSerializers(instance.membership_set.get(group=instance.id, person=i['id'])).data['invite_reason'] i['invite_reason'] = reason representation['members'].append(i) return representation class Meta: model = Group fields = '__all__'
from Membership angle , He is building two models (Group,Person) Multiple pairs of 1 Relationship ,Django When it starts , Will be automatically created on its associated model "[model]_set" Properties of , Just like the regular many to one relationship —— In fact, he is a regular many to one relationship , It's just Person Let it play another role .
reason = MembershipSerializers(instance.membership_set.get(group=instance.id, person=i[‘id’])).data[‘invite_reason’]
instance.membership_set.get(group=instance.id, person=i[‘id’]) group and person Jointly find out the reason for the invitation
person and group Model membership The default names of objects will be membership_set. So pass instance.membership_set.get() You can see group All relationships under
person All under membership:
# def to_representation(self, instance): # representation = super(PersonSerializers, self).to_representation(instance) # representation['reason'] = MembershipSerializers(instance.membership_set, many=True).data # return representation
This is about Django Explain in detail how to use many to many through This is the end of the article on customizing the intermediate table method , More about Django through Please search the previous articles of SDN or continue to browse the related articles below. I hope you can support SDN more in the future !