1👍
✅
Since Django 1.8, Conditional Expressions (SQL
‘s Case..When..
) are supported.
Thus the following django ORM single update statement should accomplish what you need
from django.db.models import Case, When, F, Q, BooleanField, Value
queryset.annotate(new_value=Case(
When(Q(stockable=False), then=Value(True)),
default=Value(False),
output_field=BooleanField()
)).update(stockable=F('new_value'))
it generates the following sql
UPDATE `yourmodel`
SET `stockable` = CASE WHEN `yourmodel`.`stocakble` = 0 THEN 1 ELSE 0 END
WHERE <queryset's filters>
for the record, here is the original, wrong solution I initially proposed
you could issue just two updates instead of looping:
queryset.filter(stockable=False).update(stockable=True)
queryset.filter(stockable=True).update(stockable=False)
which will flip the flag with two update statements
0👍
You can try to use the bulk update which fires single query for bunch of records instead of one query per record.
def make_stockable_unstockable(self, queryset):
queryset.filter(stockable=False).update(stockable=True)
queryset.filter(stockable=True).update(stockable=False)
Source:stackexchange.com