summaryrefslogtreecommitdiff
path: root/django/db/models/query_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/db/models/query_utils.py')
-rw-r--r--django/db/models/query_utils.py29
1 files changed, 29 insertions, 0 deletions
diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
index 746efce67f..9b5824f89f 100644
--- a/django/db/models/query_utils.py
+++ b/django/db/models/query_utils.py
@@ -8,12 +8,16 @@ circular import difficulties.
import copy
import functools
import inspect
+import logging
from collections import namedtuple
from django.core.exceptions import FieldError
+from django.db import DEFAULT_DB_ALIAS, DatabaseError
from django.db.models.constants import LOOKUP_SEP
from django.utils import tree
+logger = logging.getLogger("django.db.models")
+
# PathInfo is used when converting lookups (fk__somecol). The contents
# describe the relation in Model terms (model Options and Fields for both
# sides of the relation. The join_field is the field backing the relation.
@@ -110,6 +114,31 @@ class Q(tree.Node):
else:
yield child
+ def check(self, against, using=DEFAULT_DB_ALIAS):
+ """
+ Do a database query to check if the expressions of the Q instance
+ matches against the expressions.
+ """
+ # Avoid circular imports.
+ from django.db.models import Value
+ from django.db.models.sql import Query
+ from django.db.models.sql.constants import SINGLE
+
+ query = Query(None)
+ for name, value in against.items():
+ if not hasattr(value, "resolve_expression"):
+ value = Value(value)
+ query.add_annotation(value, name, select=False)
+ query.add_annotation(Value(1), "_check")
+ # This will raise a FieldError if a field is missing in "against".
+ query.add_q(self)
+ compiler = query.get_compiler(using=using)
+ try:
+ return compiler.execute_sql(SINGLE) is not None
+ except DatabaseError as e:
+ logger.warning("Got a database error calling check() on %r: %s", self, e)
+ return True
+
def deconstruct(self):
path = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
if path.startswith("django.db.models.query_utils"):