我有一个奇怪的问题,我无法解释。
我有一个django项目,周围有一些旧的陈旧物品。例如,假设我的对象看起来像这样:
class blog_post(models.Model):
user_account = models.ForeignKey('accounts.Account')
text = models.CharField(max_length=255)
authors = models.ManyToManyField(author)
created = models.DateTimeField(blank=True, null=True)
这不是我的模型的精确副本,但足够接近。
我已经创建了一个管理命令来构建这些对象的有序查询集,然后使用Paginator进行删除
我的命令看起来像这样:
all_accounts = Account.objects.all()
for act in all_accounts.iterator():
stale_objects = blog_post.objects.filter(user_account=act,
created=django.utils.timezone.now() - datetime.timedelta(days=7))
paginator = Paginator(stale_objects.order_by('id'), 100)
for page in range(1, paginator.num_pages + 1):
page_stale_objects = blog_post.objects.filter(id__in=paginator.page(page).object_list.values_list('id'))
page_stale_objects.delete()
我遇到的问题是,在使用my命令删除这些对象后,仍然存在符合查询集参数但未删除的对象。因此,我必须运行命令3次以正确查找和删除所有对象。
我首先想到我的日期范围在日期时间的边缘非常奇怪,所以在命令时间过去1周之后不久就捕捉到对象。事实并非如此,我已从查询集中删除了created = ...过滤器,并且结果相同。
为什么我的查询集在第一次运行此命令时没有捕获所有对象?没有多余的物体,最多约30,000行。
答案 0 :(得分:1)
通过查询集进行分页会转换为连续的LIMIT / OFFSET调用。所以,想想序列:
但是等等!删除第一个集后,查询集现在再次从0开始。现在从0到20的项目被跳过。
解决方案是,不要这样做。分页用于显示对象,而不是删除它们。
答案 1 :(得分:0)
如果您只想删除查询集,我不明白为什么要使用Paginator。如果我错了,请纠正我,但看起来你正在做以下事情:
当你可以这样做时:
如果您有很多对象,这将是一个巨大的性能提升。
所以,我建议你这样做:
stale_objects = blog_post.objects.filter(...)
stale_objects.delete()
希望它有所帮助!