Фильтр по новому обновленному набору запросов возвращает пустой набор запросов, используя ORM Django
при выполнении цикла queryset
и обновлении поля в модели с помощью функции save()
, затем попытке фильтрации по обновленному набору запросов, результат фильтрации возвращается пустым, даже если в наборе запросов еще есть элементы, удовлетворяющие условию.
пожалуйста, проверьте код ниже.
qs = queryset.filter(status=models.BankTransfer.STATUS_NEW)
for bank_transfer in qs:
bank_transfer.status = models.BankTransfer.STATUS_APPROVED
bank_transfer.save()
Btw когда я печатаю qs
, он возвращает результаты, но я пытаюсь получить первый объект с помощью first()
, он возвращает 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 qs.filter(purpose__status='pending_completed'):
purpose = bank_transfer.purpose
purpose.status = 'completed'
purpose.save()
for bank_transfer in qs:
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'
).update(status='completed')
qs.update(
status=models.BankTransfer.STATUS_APPROVED
)
это обновляет таблицы массово, то есть без перечисления объектов в слое Django/Python, а с помощью UPDATE …
запроса.