Opened 14 years ago

Closed 13 years ago

#14029 closed Bug (duplicate)

not operator on F objects silently fails

Reported by: Ramiro Morales Owned by: Marcos Moyano
Component: Database layer (models, ORM) Version: 1.2
Severity: Normal Keywords:
Cc: Mike Hurt Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

[On behalf of Matías Bellone aka toote that got his submission rejected as SPAM]

Trying to make a toggle action in the admin on a BooleanField lead me to very simple and straightforward code inside the ModelAdmin subclass. Problem is that it didn't work and no error was presented whatsoever. Even worse, the update actually executes something that modifies the queryset but I haven't found a way to identify how to get the query executed.

The model can be just as simple as:

from django.db.models import Model, BooleanField
 
class TestModel(Model):
    field1 = BooleanField()

Testing the "action" in an interactive shell has the same results:

$ ./manage.py shell
Python 2.6.5+ (release26-maint, Jul  6 2010, 12:58:20)
[GCC 4.4.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from models import TestModel
>>> a = TestModel.objects.all()
>>> for instance in a:
...     print instance.field1
...
True
True
>>> from django.db.models import F
>>> a = TestModel.objects.all()
>>> # to return to having a non-executed queryset
>>> a.update(field1=not F('field1'))
2
>>> a = TestModel.objects.all()
>>> for instance in a:
...     print instance.field1
...
True
True


Further tests with the debug_toolbar shows that no matter what the original values of field1 is the update will set it to true (tested on querysets with 1 and 2 instances with all possible combinations of field1 values).

Change History (8)

comment:1 by Alex Gaynor, 14 years ago

Probably __nonzero__ should just raise an exception, and we should add invert to F().

comment:2 by Daniel F Moisset, 13 years ago

Triage Stage: UnreviewedAccepted

comment:3 by Marcos Moyano, 13 years ago

Owner: changed from nobody to Marcos Moyano
Status: newassigned

comment:4 by Marcos Moyano, 13 years ago

I think a query like field=~Q('field') wouldn't be valid (or usefull) since it will query items with a negated value than the actual value, this giving an empty result all the time.
ie:

SELECT "ticket_14029_testmodel"."id", "ticket_14029_testmodel"."field1" FROM "ticket_14029_testmodel" WHERE NOT "ticket_14029_testmodel"."field1" = "ticket_14029_testmodel"."field1" LIMIT 21;

comment:5 by Marcos Moyano, 13 years ago

s/Q/F/

comment:6 by Julien Phalip, 13 years ago

Severity: Normal
Type: Bug

comment:7 by Mike Hurt, 13 years ago

Cc: Mike Hurt added
Easy pickings: unset
UI/UX: unset

comment:8 by Ramiro Morales, 13 years ago

Resolution: duplicate
Status: assignedclosed

#16211 asked for the same feature, and altough it is newer it has a patch. So I'm going to close this one.

Note: See TracTickets for help on using tickets.
Back to Top