hardik24
hardik24

Reputation: 1058

How do i created multiple connected objects at once in Django Rest Framework?

I have following model in my Django Model

class Match(models.Model):

    initiator = models.ForeignKey('CustomUser', related_name='match_initiator', on_delete=models.CASCADE)
    matched_person = models.ForeignKey('CustomUser', related_name='matched_person', on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now=True)
    algo_version = models.IntegerField()
    room_no = models.ForeignKey('Room', related_name='room_match', on_delete=models.CASCADE, null=True, blank=True)


class Room(models.Model):

    name = models.CharField(max_length=20, unique=True)
    members = models.ManyToManyField(CustomUser, related_name="joined_rooms")
    created_at = models.DateTimeField(auto_now=True,editable=False)
    is_active = models.BooleanField(default=True)

So basically I have two models, Room and Match with Match having a foreign key to a room. Now I want to create both of these objects at once, but I can not do it as first I have to create Room object get the id of it and assign it to Match object instance and then save it again. Problem with this is that if any of the model save is failed, it breaks the code.

Is there any way I can create both Match and Room object at once?

I have found this reference in Django Documentation: But I am not sure whether Django handle it automatically or do I need to handle it.

Thanks in advance!!!

Upvotes: 1

Views: 774

Answers (3)

gdef_
gdef_

Reputation: 1936

You can use atomic transactions to save both objects or none if something fails.

from django.db import IntegrityError, transaction

def your_function(...):
    try:
        with transaction.atomic():
            room = Room.objects.create(...)
            match = Match.objects.create(room_no=room, ...)
            ....
    except IntegrityError:
        handle_exception()

If something inside the transaction fails nothing will be saved.

Upvotes: 1

VnC
VnC

Reputation: 2026

You can simply use:

try:
    room = Room.objects.create(...)
    Match.objects.create(room=room, ...)
except:
    print('Catch exception here...')

Upvotes: 0

schillingt
schillingt

Reputation: 13731

You'll need to handle it yourself if your serializers are nested.

What it may look like is the following. This is entirely a guess since I don't have existing serializers to work off of, but I hope it'll help you understand the goal.

class MatchSerializer(serializers.ModelSerializer):
    room = RoomSerializer()

    class Meta:
        model = Match
        fields = (...)

    def create(self, validated_data):
        room_data = validated_data.pop('room')
        room = Room.objects.create(**profile_data)
        validated_data['room'] = room
        return super().create(self, validated_data)

You'll also need to handle the update method which was also mentioned in the documentation you linked to.

Upvotes: 1

Related Questions