summaryrefslogtreecommitdiff
path: root/django/db/models/query_utils.py
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2019-11-15 16:20:07 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-11-18 14:06:51 +0100
commit11e327a3ff84e16ceace13ea6ec408a93ca9e72c (patch)
tree438e482ac75e6ae404920493a628eb00e7519e59 /django/db/models/query_utils.py
parentcbe4d6203ff2d702b63dae52adbe7a50830a5cbe (diff)
downloaddjango-11e327a3ff84e16ceace13ea6ec408a93ca9e72c.tar.gz
Fixed #30988 -- Deprecated the InvalidQuery exception.
It was barely documented without pointers at its defining location and was abused to prevent misuse of the QuerySet field deferring feature.
Diffstat (limited to 'django/db/models/query_utils.py')
-rw-r--r--django/db/models/query_utils.py37
1 files changed, 31 insertions, 6 deletions
diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
index a9abf8d025..a6b7154541 100644
--- a/django/db/models/query_utils.py
+++ b/django/db/models/query_utils.py
@@ -8,10 +8,13 @@ circular import difficulties.
import copy
import functools
import inspect
+import warnings
from collections import namedtuple
+from django.core.exceptions import FieldDoesNotExist, FieldError
from django.db.models.constants import LOOKUP_SEP
from django.utils import tree
+from django.utils.deprecation import RemovedInDjango40Warning
# PathInfo is used when converting lookups (fk__somecol). The contents
# describe the relation in Model terms (model Options and Fields for both
@@ -19,8 +22,29 @@ from django.utils import tree
PathInfo = namedtuple('PathInfo', 'from_opts to_opts target_fields join_field m2m direct filtered_relation')
-class InvalidQuery(Exception):
- """The query passed to raw() isn't a safe query to use with raw()."""
+class InvalidQueryType(type):
+ @property
+ def _subclasses(self):
+ return (FieldDoesNotExist, FieldError)
+
+ def __warn(self):
+ warnings.warn(
+ 'The InvalidQuery exception class is deprecated. Use '
+ 'FieldDoesNotExist or FieldError instead.',
+ category=RemovedInDjango40Warning,
+ stacklevel=4,
+ )
+
+ def __instancecheck__(self, instance):
+ self.__warn()
+ return isinstance(instance, self._subclasses) or super().__instancecheck__(instance)
+
+ def __subclasscheck__(self, subclass):
+ self.__warn()
+ return issubclass(subclass, self._subclasses) or super().__subclasscheck__(subclass)
+
+
+class InvalidQuery(Exception, metaclass=InvalidQueryType):
pass
@@ -233,10 +257,11 @@ def select_related_descend(field, restricted, requested, load_fields, reverse=Fa
if load_fields:
if field.attname not in load_fields:
if restricted and field.name in requested:
- raise InvalidQuery("Field %s.%s cannot be both deferred"
- " and traversed using select_related"
- " at the same time." %
- (field.model._meta.object_name, field.name))
+ msg = (
+ 'Field %s.%s cannot be both deferred and traversed using '
+ 'select_related at the same time.'
+ ) % (field.model._meta.object_name, field.name)
+ raise FieldError(msg)
return True