[Fixed]-Action vise versa in Admin Django

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

👤zsepi

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)

Leave a comment