加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 在数据在其他地方更改时迭代大型Django查询集

发布时间:2020-12-20 11:12:37 所属栏目:Python 来源:网络整理
导读:迭代查询集,如下所示: 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()
迭代查询集,如下所示:

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正在增加,而这正在发生.如果在运行此cronjob时修改book.views,则会恢复它.

现在,book.views没有被cronjob修改,但它在.all()queryset调用期间被缓存.当book.save()时,我感觉它正在使用旧的book.views值.

有没有办法确保只更新活动字段?或者,假设有10万本书.这需要很长时间才能运行.但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()

解决方法

以下将在Django 1.1中为您完成工作,无需循环:

from django.db.models import F
Book.objects.all().update(activity=F('views')*4)

您也可以进行更复杂的计算:

for book in Book.objects.all().iterator():
    Book.objects.filter(pk=book.pk).update(activity=book.calculate_activity())

这两个选项都有可能使活动字段与其余部分不同步,但我认为你可以使用它,因为你在cron作业中计算它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读