简体   繁体   中英

database tranactions in django for dependent operations

I am new to Django and have some model definitions as follows:

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"

I have an associated view which allows the user to create a project and a study at the same time. I do it as follows:

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)

I have been thinking about how to do this so that if any of the operations fail, the database stays untouched ie if the study is not created for some reason, the project is not created either.

One way i thought it is doable is to mark the method savepoints before calling the objects.create and then rolling back in the exception handler. However, I am not sure if that is the right way to do this.

Use transaction.atomic (like you have commented out) to wrap operations into single, database transaction.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM