我如何在 Django Rest Framework 中一次创建多个连接的对象?
How do i created multiple connected objects at once in Django Rest Framework?
我的 Django 模型中有以下模型
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)
所以基本上我有两个模型,Room
和 Match
,Match 有一个房间的外键。现在我想同时创建这两个对象,但我不能这样做,因为首先我必须创建 Room 对象并获取它的 id 并将其分配给 Match 对象实例,然后再次保存它。问题在于,如果任何模型保存失败,就会破坏代码。
有什么方法可以同时创建 Match 和 Room 对象?
我在 Django 文档中找到了这个 reference:但是我不确定 Django 是自动处理它还是我需要处理它。
提前致谢!!!
如果你的序列化器是嵌套的,你需要自己处理。
它可能看起来像下面这样。这完全是一个猜测,因为我没有现有的序列化程序可以使用,但我希望它能帮助您理解目标。
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)
您还需要处理 update
方法,您链接到的文档中也提到了该方法。
您可以使用 atomic transactions 来保存两个对象,或者如果出现问题则使用 none。
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()
如果交易中的某些内容失败,则不会保存任何内容。
您可以简单地使用:
try:
room = Room.objects.create(...)
Match.objects.create(room=room, ...)
except:
print('Catch exception here...')
我的 Django 模型中有以下模型
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)
所以基本上我有两个模型,Room
和 Match
,Match 有一个房间的外键。现在我想同时创建这两个对象,但我不能这样做,因为首先我必须创建 Room 对象并获取它的 id 并将其分配给 Match 对象实例,然后再次保存它。问题在于,如果任何模型保存失败,就会破坏代码。
有什么方法可以同时创建 Match 和 Room 对象?
我在 Django 文档中找到了这个 reference:但是我不确定 Django 是自动处理它还是我需要处理它。
提前致谢!!!
如果你的序列化器是嵌套的,你需要自己处理。
它可能看起来像下面这样。这完全是一个猜测,因为我没有现有的序列化程序可以使用,但我希望它能帮助您理解目标。
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)
您还需要处理 update
方法,您链接到的文档中也提到了该方法。
您可以使用 atomic transactions 来保存两个对象,或者如果出现问题则使用 none。
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()
如果交易中的某些内容失败,则不会保存任何内容。
您可以简单地使用:
try:
room = Room.objects.create(...)
Match.objects.create(room=room, ...)
except:
print('Catch exception here...')