Django一旦获取切片,就无法更新查询

时间:2013-08-27 14:15:34

标签: python django

我有一个查询...

message_batch = Message.objects.all()[500]

我不想再进行另一个数据库调用来检索对象,除了我已经将它们放在内存中,所以重点是什么。

所以我试着像这样更新:

message_batch.update(send_date=datetime.datetime.now(), status="Sent")

但是我收到以下错误消息:

切片拍摄后无法更新查询。

为什么呢?周围有这个吗?我想更新我已经在内存中的对象而不是再次调用来检索它们。

这是我的完整代码,必须解决这个问题....

total = Message.objects.filter(status="Unsent", sender=user,   batch=batch).exclude(recipient_number__exact='').count()

for i in xrange(0,total,500):
    message_batch = Message.objects.filter(status="Unsent").exclude(recipient_number__exact='')[i:i+500]
    # do some stuff here
    # once all done update the objects
    message_batch.update(send_date=datetime.datetime.now(), billed=True)

2 个答案:

答案 0 :(得分:2)

使用django数据库事务获得最佳性能:

https://docs.djangoproject.com/en/1.5/topics/db/transactions/

例如:

from django.db import transaction

total = Message.objects.filter(status="Unsent", sender=user, batch=batch).exclude(recipient_number__exact='').count()

    for i in xrange(0,total,500):
        message_batch = Message.objects.filter(status="Unsent").exclude(recipient_number__exact='')[i:i+500]
        # do some stuff here
        #once all done update the objects
        message_batch.update(send_date=datetime.datetime.now(), billed=True)

        with transaction.commit_on_success():
            for m in message_batch:
                m.update(send_date=datetime.datetime.now(), billed=True)                    

这将包装例如。如果您不在事务中执行更新,则5000行更新为对数据库的一次调用,而不是调用数据库5000次。

答案 1 :(得分:0)

您可以按主键更新对象:

base_qs = Message.objects.filter(status="Unsent", sender=user, batch=batch).exclude(recipient_number__exact='')
total = base_qs.count()

for i in xrange(0, total, 500):
    page = list(base_qs[i:i+500])
    page_ids = [o.pk for o in page]
    # Do some stuff here
    base_qs.filter(pk__in=page_ids).update(send_date=datetime.datetime.now(), billed=True)
相关问题