Last active
March 19, 2023 13:54
-
-
Save ph3b/98b9aeaff4f86527dc5a523f321cac7e to your computer and use it in GitHub Desktop.
DRF - ManyToMany, intermediate model and custom save/update
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Assumes members already exist with id 1 and 2. | |
{ | |
"name": "My group 1", | |
"members": [ | |
{ "id": 1, "role": "Leader" }, | |
{ "id": 2, "role": "Regular" } | |
] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import unicode_literals | |
from django.db import models | |
class Member(models.Model): | |
name = models.CharField(max_length=50) | |
def __unicode__(self): | |
return self.name | |
class Group(models.Model): | |
name = models.CharField(max_length=50) | |
members = models.ManyToManyField(Member, blank=True, related_name='groups', through="GroupMember") | |
def __unicode__(self): | |
return self.name | |
class GroupMember(models.Model): | |
member = models.ForeignKey(Member, on_delete=models.CASCADE) | |
group = models.ForeignKey(Group, on_delete=models.CASCADE) | |
role = models.CharField(max_length=40) | |
def __unicode__(self): | |
return self.member.name + " " + self.group.name + " - " + self.role |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework import serializers | |
from models import Group, Member, GroupMember | |
from django.db import transaction | |
class MemberSerializer(serializers.ModelSerializer): | |
class Meta: | |
model = Member | |
fields = ('id', 'name', 'groups') | |
class GroupMemberSerializer(serializers.ModelSerializer): | |
id = serializers.ReadOnlyField(source='member.id') | |
name = serializers.ReadOnlyField(source='member.name') | |
class Meta: | |
model = GroupMember | |
fields = ('id', 'name', 'role') | |
class GroupSerializer(serializers.ModelSerializer): | |
members = GroupMemberSerializer(source="groupmember_set", many=True, read_only=True) | |
class Meta: | |
model = Project | |
fields = '__all__' | |
depth = 1 | |
@transaction.atomic | |
def update(self, instance, validated_data): | |
GroupMember.objects.filter(group=instance).delete() | |
members = self.initial_data.get("members") | |
for member in members: | |
id = member.get("id") | |
role = member.get("role") | |
new_member = Member.objects.get(pk=id) | |
GroupMember(group=instance, member=new_member, role=role).save() | |
instance.__dict__.update(**validated_data) | |
instance.save() | |
return instance | |
@transaction.atomic | |
def create(self, validated_data): | |
group = Group.objects.create(**validated_data) | |
if "members" in self.initial_data: | |
members = self.initial_data.get("members") | |
for member in members: | |
id = member.get("id") | |
role = member.get("role") | |
member_instance = Member.objects.get(pk=id) | |
GroupMember(group=group, member=member_instance, role=role).save() | |
group.save() | |
return project |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework import viewsets | |
from models import Group, Member | |
from serializers import GroupSerializer, MemberSerializer | |
class GroupViewSet(viewsets.ModelViewSet): | |
queryset = Group.objects.all() | |
serializer_class = GroupSerializer | |
class MemberViewSet(viewsets.ModelViewSet): | |
queryset = Member.objects.all() | |
serializer_class = MemberSerializer |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment