[Django] #31783: Filtering on a field named `negate` raises a TypeError

67 views
Skip to first unread message

Django

unread,
Jul 13, 2020, 3:23:12 PM7/13/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron | Owner: nobody
Kirkbride |
Type: Bug | Status: new
Component: Database | Version: 3.0
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Filtering on a model with a field named `negate` raises a `TypeError`.

For example:
{{{
class Foo(models.Model):
negate = models.BooleanField()

Foo.objects.filter(negate=True)
}}}

raises `TypeError: _filter_or_exclude() got multiple values for argument
'negate'`

`negate` is not documented as a reserved argument for `.filter()`. I'm
currently using `.filter(negate__exact=True)` as a workaround.

--
Ticket URL: <https://code.djangoproject.com/ticket/31783>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jul 13, 2020, 8:26:22 PM7/13/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron Kirkbride | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* easy: 0 => 1
* stage: Unreviewed => Accepted


Comment:

We should either document this limitation or change `_filter_or_exclude`
and friends signature from `(negate, *args, **kwargs)` to `(negate, args,
kwargs)`.

I think the second approach is favourable as there's not much benefits in
using arguments unpacking in these private methods.

--
Ticket URL: <https://code.djangoproject.com/ticket/31783#comment:1>

Django

unread,
Jul 13, 2020, 8:49:14 PM7/13/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron Kirkbride | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

Aaron, would you be interested in submitting a PR with the changes below
plus a regression test in `tests/query/tests.py`?

{{{#!diff
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 07d6ffd4ca..d655ede8d9 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -204,7 +204,7 @@ class QuerySet:
def query(self):
if self._deferred_filter:
negate, args, kwargs = self._deferred_filter
- self._filter_or_exclude_inplace(negate, *args, **kwargs)
+ self._filter_or_exclude_inplace(negate, args, kwargs)
self._deferred_filter = None
return self._query

@@ -939,7 +939,7 @@ class QuerySet:
set.
"""
self._not_support_combined_queries('filter')
- return self._filter_or_exclude(False, *args, **kwargs)
+ return self._filter_or_exclude(False, args, kwargs)

def exclude(self, *args, **kwargs):
"""
@@ -947,9 +947,9 @@ class QuerySet:
set.
"""
self._not_support_combined_queries('exclude')
- return self._filter_or_exclude(True, *args, **kwargs)
+ return self._filter_or_exclude(True, args, kwargs)

- def _filter_or_exclude(self, negate, *args, **kwargs):
+ def _filter_or_exclude(self, negate, args, kwargs):
if args or kwargs:
assert not self.query.is_sliced, \
"Cannot filter a query once a slice has been taken."
@@ -959,10 +959,10 @@ class QuerySet:
self._defer_next_filter = False
clone._deferred_filter = negate, args, kwargs
else:
- clone._filter_or_exclude_inplace(negate, *args, **kwargs)
+ clone._filter_or_exclude_inplace(negate, args, kwargs)
return clone

- def _filter_or_exclude_inplace(self, negate, *args, **kwargs):
+ def _filter_or_exclude_inplace(self, negate, args, kwargs):
if negate:
self._query.add_q(~Q(*args, **kwargs))
else:
@@ -983,7 +983,7 @@ class QuerySet:
clone.query.add_q(filter_obj)
return clone
else:
- return self._filter_or_exclude(False, **filter_obj)
+ return self._filter_or_exclude(False, args=(),
kwargs=filter_obj)

def _combinator_query(self, combinator, *other_qs, all=False):
# Clone the query to inherit the select list and everything
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31783#comment:2>

Django

unread,
Jul 14, 2020, 5:09:24 AM7/14/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron Kirkbride | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Aaron Kirkbride):

Replying to [comment:2 Simon Charette]:


> Aaron, would you be interested in submitting a PR with the changes below
plus a regression test in `tests/query/tests.py`?

Sure! I can do that this evening.

--
Ticket URL: <https://code.djangoproject.com/ticket/31783#comment:3>

Django

unread,
Jul 14, 2020, 5:10:06 AM7/14/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron Kirkbride | Owner: Aaron
| Kirkbride
Type: Bug | Status: assigned

Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Aaron Kirkbride):

* owner: nobody => Aaron Kirkbride
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/31783#comment:4>

Django

unread,
Jul 28, 2020, 8:24:17 AM7/28/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron Kirkbride | Owner: Hasan
| Ramezani

Type: Bug | Status: assigned
Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Hasan Ramezani):

* owner: Aaron Kirkbride => Hasan Ramezani
* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/31783#comment:5>

Django

unread,
Jul 28, 2020, 8:38:32 AM7/28/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron Kirkbride | Owner: Hasan
| Ramezani
Type: Bug | Status: assigned
Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Aaron Kirkbride):

Replying to [comment:5 Hasan Ramezani]:

Thanks Hasan for creating the PR :) Sorry I didn't get round to this
earlier.

--
Ticket URL: <https://code.djangoproject.com/ticket/31783#comment:6>

Django

unread,
Jul 28, 2020, 9:31:45 AM7/28/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron Kirkbride | Owner: Hasan
| Ramezani
Type: Bug | Status: assigned
Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/31783#comment:7>

Django

unread,
Jul 29, 2020, 3:03:37 AM7/29/20
to django-...@googlegroups.com
#31783: Filtering on a field named `negate` raises a TypeError
-------------------------------------+-------------------------------------
Reporter: Aaron Kirkbride | Owner: Hasan
| Ramezani
Type: Bug | Status: closed

Component: Database layer | Version: 3.0
(models, ORM) |
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"9c9a3fe1180fc92fbd4c3302dbe0b3e083bf0381" 9c9a3fe1]:
{{{
#!CommitTicketReference repository=""
revision="9c9a3fe1180fc92fbd4c3302dbe0b3e083bf0381"
Fixed #31783 -- Fixed crash when filtering againts "negate" field.

Thanks Simon Charette for the initial patch.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31783#comment:8>

Reply all
Reply to author
Forward
0 new messages