1

I have a query...

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

I don't want to have to make another database call to retrieve the objects, besides I already have them in memory so whats the point.

So I tried to update like this:

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

But I get the following error message:

Cannot update a query once a slice has been taken.

Why? Is there a around around this? I want to update the objects I already have in memory not make another call to retrieve them.

This is my full code, has to be way around this....

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

2 回答 2

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 次。

于 2013-08-27T14:39:46.660 回答
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)
于 2013-08-27T15:23:17.613 回答