Django - 在单个 Django 端点中创建具有关系的多个不同对象
Django - Create multiple different objects with relations in single Django endpoint
有没有办法创建一个端点来创建多个对象?相反,我一直在做的是接收请求数据并一次创建一个对象,如果一个失败,则删除以前创建的实体,这看起来真的很老套,必须有更好的方法来创建多个对象。因此,基本上所有 Post
都需要与 Goal
相关联,因此当请求到来时,它将伴随 post 相关数据和 request.data
中的目标相关数据。所以它应该首先创建 Goal
然后是与之关联的 Post
。有没有办法一次性做到这一点?我的假设是创建一个自定义序列化程序来处理这个问题,但不确定如何雄辩地处理如果 Post
无法创建我应该删除 Goal
.
的情况
model.py
class Goal(AbstractBaseModel):
creator_uuid = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, related_name="goal_creator_uuid")
goal_category = models.ForeignKey(GoalCategory, on_delete=models.CASCADE)
description = models.CharField(max_length=150, validators=[MinLengthValidator(5)])
class Post(AbstractBaseModel):
creator_uuid = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="post_creator_uuid")
goal_uuid = models.ForeignKey(Goal, on_delete=models.CASCADE)
body = post_body
view.py
def post(request):
"""
POST endpoint for current user creating a goal update post
"""
goal_serializer = GoalSerializer(data=request.data)
if goal_serializer.is_valid():
goal_obj = goal_serializer.save()
else:
# return 400 Response
request.data['goal_uuid'] = str(goal_obj.uud)
post_serializer = PostSerializer(data=request.data)
if post_serializer.is_valid():
post_serializer.save()
else:
goal_obj.delete()
# return 400 Response
# return 200 Response
您可以使用 try...except
将这些序列化程序包装在一个原子块中,如下所示:
from rest_framework.exceptions import ValidationError
def post(request):
try:
with transaction.atomic():
goal_serializer = GoalSerializer(data=request.data)
goal_serializer.is_valid(raise_exception=True)
goal_obj = goal_serializer.save()
request.data['goal_uuid'] = str(goal_obj.uud)
post_serializer = PostSerializer(data=request.data)
post_serializer.is_valid(raise_exception=True)
post_serializer.save()
except ValidationError as e:
# return 400 Response with e as details
# return 200 Response
当序列化程序验证失败时(或者如果引发任何异常),它将自动回滚 atomic
块中的所有内容。然后您可以捕获 ValidationError
并构建您需要的响应。
有没有办法创建一个端点来创建多个对象?相反,我一直在做的是接收请求数据并一次创建一个对象,如果一个失败,则删除以前创建的实体,这看起来真的很老套,必须有更好的方法来创建多个对象。因此,基本上所有 Post
都需要与 Goal
相关联,因此当请求到来时,它将伴随 post 相关数据和 request.data
中的目标相关数据。所以它应该首先创建 Goal
然后是与之关联的 Post
。有没有办法一次性做到这一点?我的假设是创建一个自定义序列化程序来处理这个问题,但不确定如何雄辩地处理如果 Post
无法创建我应该删除 Goal
.
model.py
class Goal(AbstractBaseModel):
creator_uuid = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, related_name="goal_creator_uuid")
goal_category = models.ForeignKey(GoalCategory, on_delete=models.CASCADE)
description = models.CharField(max_length=150, validators=[MinLengthValidator(5)])
class Post(AbstractBaseModel):
creator_uuid = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="post_creator_uuid")
goal_uuid = models.ForeignKey(Goal, on_delete=models.CASCADE)
body = post_body
view.py
def post(request):
"""
POST endpoint for current user creating a goal update post
"""
goal_serializer = GoalSerializer(data=request.data)
if goal_serializer.is_valid():
goal_obj = goal_serializer.save()
else:
# return 400 Response
request.data['goal_uuid'] = str(goal_obj.uud)
post_serializer = PostSerializer(data=request.data)
if post_serializer.is_valid():
post_serializer.save()
else:
goal_obj.delete()
# return 400 Response
# return 200 Response
您可以使用 try...except
将这些序列化程序包装在一个原子块中,如下所示:
from rest_framework.exceptions import ValidationError
def post(request):
try:
with transaction.atomic():
goal_serializer = GoalSerializer(data=request.data)
goal_serializer.is_valid(raise_exception=True)
goal_obj = goal_serializer.save()
request.data['goal_uuid'] = str(goal_obj.uud)
post_serializer = PostSerializer(data=request.data)
post_serializer.is_valid(raise_exception=True)
post_serializer.save()
except ValidationError as e:
# return 400 Response with e as details
# return 200 Response
当序列化程序验证失败时(或者如果引发任何异常),它将自动回滚 atomic
块中的所有内容。然后您可以捕获 ValidationError
并构建您需要的响应。