Фильтр по новому обновленному набору запросов возвращает пустой набор запросов, используя 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 … запроса.

Вернуться на верх