使用 ORM Django 过滤新更新的查询集 return 空查询集
filter on new updated queryset return empty queryset using ORM Django
当使用 save()
函数在模型中循环 queryset
和更新字段时,然后尝试对更新的查询集进行过滤,过滤结果 returns 为空,即使仍然有查询集中满足条件的元素。
请检查下面的代码。
qs = queryset.filter(status=models.BankTransfer.STATUS_NEW)
for bank_transfer in qs:
bank_transfer.status = models.BankTransfer.STATUS_APPROVED
bank_transfer.save()
顺便说一句,当我打印 qs
时,它 returns 有结果,但我尝试使用 first()
来获取第一个对象,它 returns None
for bank_transfer in qs.filter(purpose__status='pending_completed'):
bank_transfer.purpose.status = 'completed'
bank_transfer.purpose.save()
银行转账模式:
class BankTransfer(models.Model):
swift_code = models.CharField(max_length=200, blank=False, verbose_name=_('SWIFT'))
user = models.ForeignKey(User, blank=False, null=True, on_delete=models.SET_NULL)
amount = models.DecimalField(blank=False, default=D('0'), max_digits=11, decimal_places=2, verbose_name=_('Amount'))
purpose = models.ForeignKey('auction.Purpose', blank=True, null=True, on_delete=models.SET_NULL)
status = models.CharField(max_length=200, blank=False, null=False, choices=STATUS_CHOICES, verbose_name=_('Status'))
用途型号:
class Purpose(models.Model):
status = models.CharField(max_length=200, blank=False, null=True, choices=STATUS_CHOICES, verbose_name=_('Status'))
bla
bla
qs
是 QuerySet
,其中的项目具有 status
STATUS_NEW
。在第一个循环中,您更新所有这些项目,使它们具有 STATUS_APPROVED
.
但是 QuerySet
本质上是您正在构建的查询。如果您调用 qs.filter(purpose__status='pending_completed')
,那么您将进行 new 查询并查找具有 status=STATUS_NEW
和 的项目purpose__status
等于 pending_completed
,这没有多大意义。
因此您应该以相反的方式处理查询集:
qs = queryset.filter(status=models.BankTransfer.STATUS_NEW)
for bank_transfer in <strong>qs.filter(purpose__status='pending_completed')</strong>:
purpose = bank_transfer.purpose
purpose.status = 'completed'
purpose.save()
for bank_transfer in <strong>qs</strong>:
bank_transfer.status = models.BankTransfer.STATUS_APPROVED
bank_transfer.save()
我们可以批量更新以提高效率:
qs = queryset.filter(status=models.BankTransfer.STATUS_NEW)
Purpose.objects.filter(
bank_transfer__in=qs,
status='pending_completed'
)<b>.update(</b>status='completed'<b>)</b>
qs<b>.update(</b>
status=models.BankTransfer.STATUS_APPROVED
<b>)</b>
这会批量更新表,因此不会枚举 Django/Python 层中的对象,但会使用 UPDATE …
查询。
当使用 save()
函数在模型中循环 queryset
和更新字段时,然后尝试对更新的查询集进行过滤,过滤结果 returns 为空,即使仍然有查询集中满足条件的元素。
请检查下面的代码。
qs = queryset.filter(status=models.BankTransfer.STATUS_NEW)
for bank_transfer in qs:
bank_transfer.status = models.BankTransfer.STATUS_APPROVED
bank_transfer.save()
顺便说一句,当我打印 qs
时,它 returns 有结果,但我尝试使用 first()
来获取第一个对象,它 returns None
for bank_transfer in qs.filter(purpose__status='pending_completed'):
bank_transfer.purpose.status = 'completed'
bank_transfer.purpose.save()
银行转账模式:
class BankTransfer(models.Model):
swift_code = models.CharField(max_length=200, blank=False, verbose_name=_('SWIFT'))
user = models.ForeignKey(User, blank=False, null=True, on_delete=models.SET_NULL)
amount = models.DecimalField(blank=False, default=D('0'), max_digits=11, decimal_places=2, verbose_name=_('Amount'))
purpose = models.ForeignKey('auction.Purpose', blank=True, null=True, on_delete=models.SET_NULL)
status = models.CharField(max_length=200, blank=False, null=False, choices=STATUS_CHOICES, verbose_name=_('Status'))
用途型号:
class Purpose(models.Model):
status = models.CharField(max_length=200, blank=False, null=True, choices=STATUS_CHOICES, verbose_name=_('Status'))
bla
bla
qs
是 QuerySet
,其中的项目具有 status
STATUS_NEW
。在第一个循环中,您更新所有这些项目,使它们具有 STATUS_APPROVED
.
但是 QuerySet
本质上是您正在构建的查询。如果您调用 qs.filter(purpose__status='pending_completed')
,那么您将进行 new 查询并查找具有 status=STATUS_NEW
和 的项目purpose__status
等于 pending_completed
,这没有多大意义。
因此您应该以相反的方式处理查询集:
qs = queryset.filter(status=models.BankTransfer.STATUS_NEW)
for bank_transfer in <strong>qs.filter(purpose__status='pending_completed')</strong>:
purpose = bank_transfer.purpose
purpose.status = 'completed'
purpose.save()
for bank_transfer in <strong>qs</strong>:
bank_transfer.status = models.BankTransfer.STATUS_APPROVED
bank_transfer.save()
我们可以批量更新以提高效率:
qs = queryset.filter(status=models.BankTransfer.STATUS_NEW)
Purpose.objects.filter(
bank_transfer__in=qs,
status='pending_completed'
)<b>.update(</b>status='completed'<b>)</b>
qs<b>.update(</b>
status=models.BankTransfer.STATUS_APPROVED
<b>)</b>
这会批量更新表,因此不会枚举 Django/Python 层中的对象,但会使用 UPDATE …
查询。