Django:有没有办法将连续的model.save()操作作为一个DB请求来执行?

2024-05-29 03:07:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个对Django模型实例执行操作的函数,我正在尝试将它分解为可以独立使用的子操作。但是,这意味着我最终会在每次更改时调用.save,并触发一个DB请求

def subop1(instance):
    instance.a1 = 1
    instance.save()

def subop1(instance):
    instance.a2 = 2
    instance.save()

def subop1(instance):
    instance.a3 = 3
    instance.save()

def main_op(instance):
    subop1(instance) # triggers 1 DB request
    subop2(instance) # triggers 1 DB request
    subop3(instance) # triggers 1 DB request

有没有办法避免每次.save触发DB请求,同时保持每个函数独立运行?也许可以采用某种方式将.save操作推迟到某个上下文管理器退出,然后使用1db请求一次保存所有操作

我试图通读transaction文档,但没有找到合适的


Tags: django实例instance函数模型a2dbmain
3条回答

您可以向方法中添加可选参数,例如:

def subop1(instance, commit=True):
    instance.a1 = 1
    if commit:
        instance.save()

然后用commit=False调用实例,然后手动调用save()

def main_op(instance):
    subop1(instance, commit=False)
    subop2(instance, commit=False)
    subop3(instance, commit=False)
    instance.save()

你可以按以下方式做

def subop1(instance):
instance.a1 = 1

def subop1(instance):
instance.a2 = 2

def subop1(instance):
instance.a3 = 3

def main_op(instance):
subop1(instance)
subop2(instance)
subop3(instance) 
instance.save() 

方法1:

实例是相同的,因此可以执行以下操作:

def subop1(instance):
    instance.a1 = 1

def subop1(instance):
    instance.a2 = 2

def subop1(instance):
    instance.a3 = 3

def main_op(instance):
    subop1(instance)
    subop2(instance)
    subop3(instance) 
    instance.save() # triggers 1 DB request

之所以可以这样做,是因为实例是一个对象,它是通过引用而不是通过值传递的

因此,如果在函数中编辑实例,更改也会保留在该方法之外

方法2:

或者你可以这样做:

from threading import Timer

class Object():
    a1 = 0
    a2 = 0
    a3 = 0

    def save(self):
        print(self.a1)
        print(self.a2)
        print(self.a3)        

def subop1(instance):
    instance.a1 = 1
    restart_timer(instance)

def subop2(instance):
    instance.a2 = 2
    restart_timer(instance)


def subop3(instance):
    instance.a3 = 3
    restart_timer(instance)


def main_op(instance):
    subop1(instance)
    subop2(instance)
    subop3(instance)

timer = None

def restart_timer(instance):
    global timer
    if timer != None:
        timer.cancel() # this delete last timer
    timer = Timer(5.0, Object.save, [instance]) # This call the save method after 5 sec
    timer.start() # This start the new timer

if __name__ == '__main__':
    obj = Object()
    main_op(obj)

请注意但是,这不是最好的方法,因为垃圾收集器可能会删除实例,因此只有在确定对象始终保持全局的情况下,才使用此方法

否则,必须将此方法添加到对象类

def __exit__(self, exc_type, exc_value, traceback):
    self.save()

注意第2部分 在这种情况下,您的项目将保存每当您处置它。 因此,如果你不主动保存对象,它无论如何都会被保存

所以最后最好的方法是在数据库上做更多的事务。

相关问题 更多 >

    热门问题