为了账号安全,请及时绑定邮箱和手机立即绑定

Django:有什么方法可以将连续的 model.save() 操作作为

Django:有什么方法可以将连续的 model.save() 操作作为

子衿沉夜 2021-07-02 14:06:14
我有一个对 Django 模型实例执行操作的函数,我试图将它分解为可以独立使用的子操作。但是,这意味着我最终会调用.save每个更改并触发数据库请求。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每次都触发数据库请求,同时仍然保持每个功能独立运行?也许某种方式将.save操作推迟到某个上下文管理器退出,然后使用 1 个 DB 请求一次性保存所有操作。试图通读transaction文档,但我没有找到任何合适的内容。
查看完整描述

3 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

您可以为方法添加一个可选参数,例如:

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()


查看完整回答
反对 回复 2021-07-13
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

方法一:


实例是相同的,所以你可以这样做:


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

你可以这样做,因为 instance 是一个对象,它是通过引用而不是通过值传递的。


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


方法二:


或者你可以做这样的事情:


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()

请注意 pt.2 在这种情况下,您的物品将在您丢弃时得到保存。所以如果你不主动保存对象,它无论如何都会被保存。


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


查看完整回答
反对 回复 2021-07-13
?
慕仙森

TA贡献1827条经验 获得超7个赞

您可以通过以下方式进行。


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() 


查看完整回答
反对 回复 2021-07-13
  • 3 回答
  • 0 关注
  • 301 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信