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 并构建您需要的响应。