Итерация по набору запросов, например так:
class Book(models.Model):
# <snip some other stuff>
activity = models.PositiveIntegerField(default=0)
views = models.PositiveIntegerField(default=0)
def calculate_statistics():
self.activity = book.views * 4
book.save()
def cron_job_calculate_all_book_statistics():
for book in Book.objects.all():
book.calculate_statistics()
... работает просто отлично. Тем не менее, это задача cron. book.views
увеличивается, пока это происходит. Если book.views
изменено во время выполнения этого cronjob, оно отменяется.
Теперь book.views
не изменяется cronjob, но он кэшируется во время вызова набора запросов .all()
. Когда book.save()
, я чувствую, что он использует старое значение book.views
.
Есть ли способ убедиться, что обновлено только поле activity
? Или, скажем, есть 100 000 книг. Это займет довольно много времени, чтобы бежать. Но book.views
будет с того момента, когда изначально запускается набор запросов. Это решение просто использовать .iterator()
?
ОБНОВЛЕНИЕ: Вот то, что я делаю эффективно. Если у вас есть идеи о том, как сделать эту работу хорошо встроенной, тогда я полностью за нее.
def calculate_statistics(self):
self.activity = self.views + self.hearts.count() * 2
# Can't do self.comments.count with a comments GenericRelation, because Comment uses
# a TextField for object_pk, and that breaks the whole system. Lame.
self.activity += Comment.objects.for_model(self).count() * 4
self.save()