Reputation: 1058
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
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
Reputation: 2026
You can simply use:
try:
room = Room.objects.create(...)
Match.objects.create(room=room, ...)
except:
print('Catch exception here...')
Upvotes: 0
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