I am learning Django. When I use F
to modify the is_show
field, I can only switch True
to False
, but cannot switch False
to True
...
@admin.action(description='switch show')
def make_switch_show(modeladmin, request, queryset):
# This code does not work properly, so I have to use `for`
# Why this code cannot work like the following `for`
# queryset.update(is_show=not F('is_show'))
for it in queryset:
it.is_show = False if it.is_show else True
it.save()
actions = [make_switch_show]
...
Some environmental information
django = "3.2.8"
Python 3.9.7
Database SQLite
CodePudding user response:
F
expressions do not bring the field value from db to Python - they construct a SQL expression to reference the field in the final query.
The reason it can switch True
to False
but not the other way around is that for Python the expression is never false - it always returns an object of type F
.
So not F('is_show')
is always False
, because it is equal to not bool(F('is_show'))
and bool(F('is_show'))
is True
. not True
is False
I don't think Django currently provides a straightforward way to negate a F
expression. You might have luck with Case