2016-11-24 78 views
0

我是新来的Django,并有一些模型定义如下:数据库tranactions对相关的操作

class ProjectModel(models.Model): 
    name = models.CharField(max_length=100) 
    description = models.TextField() 

    class Meta: 
     db_table = "projects" 

class StudyModel(models.Model): 
    project = models.ForeignKey(ProjectModel) 
    name = models.CharField(max_length=100) 
    description = models.TextField() 

    class Meta: 
     db_table = "studies" 

我有一个相关的视图,它允许用户创建同时项目和研究。我这样做如下:

pid = ProjectModel.objects.filter(name__iexact=project_name).first() 
    if pid is None: 
     try: 
      #with transaction.atomic(): 
      pobj = ProjectModel.objects.create(name="A", description="") 
      sobj = StudyModel.objects.create(name="B", description="", project_id=pobj.pk) 

      except: 
       #pobj.delete() 
       #sobj.delete() 
       return Response(status=status.HTTP_417_EXPECTATION_FAILED) 

我一直在思考如何做到这一点,因此如果任何操作失败,即如果study不是出于某种原因创建的数据库保持不变,则project不创建。

我认为这是可行的方法之一是在调用objects.create之前标记方法savepoints,然后回滚到异常处理程序中。但是,我不确定这是否是正确的方法。

回答

1

使用transaction.atomic(如您已注释掉)将操作封装到单个数据库事务中。

from django.db import DatabaseError, transaction 

if pid is None: 
    try: 
     with transaction.atomic(): 
      pobj = ProjectModel.objects.create(name="A", description="") 
      sobj = StudyModel.objects.create(name="B", description="", project_id=pobj.pk) 
    except DatabaseError: 
     return Response(status=status.HTTP_417_EXPECTATION_FAILED) 
+0

好的,所以我想我不必担心展开....这是之前给出的错误,但我意识到它来自另一个来源... – Luca