summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Bistuer <loic.bistuer@sixmedia.com>2013-07-29 16:47:49 +0700
committerTim Graham <timograham@gmail.com>2013-07-31 09:54:00 -0400
commitacd1d439fd9b3e77bc0291dcd62c09f345d8622c (patch)
treeda3c4ca49f1395392ce3dfc7414dcd6cb2c21718
parenta3a59a3197d4e03c5c016edc581bfc5f25668bca (diff)
Fixed #20826 -- Moved Manager.raw() and Manager._insert() to the QuerySet class.
-rw-r--r--django/db/models/manager.py8
-rw-r--r--django/db/models/query.py37
-rw-r--r--docs/ref/models/querysets.txt22
-rw-r--r--tests/basic/tests.py2
4 files changed, 49 insertions, 20 deletions
diff --git a/django/db/models/manager.py b/django/db/models/manager.py
index f57944ebbc..4f16b5ebfe 100644
--- a/django/db/models/manager.py
+++ b/django/db/models/manager.py
@@ -2,7 +2,7 @@ import copy
import inspect
from django.db import router
-from django.db.models.query import QuerySet, insert_query, RawQuerySet
+from django.db.models.query import QuerySet
from django.db.models import signals
from django.db.models.fields import FieldDoesNotExist
from django.utils import six
@@ -169,12 +169,6 @@ class BaseManager(six.with_metaclass(RenameManagerMethods)):
# understanding of how this comes into play.
return self.get_queryset()
- def _insert(self, objs, fields, **kwargs):
- return insert_query(self.model, objs, fields, **kwargs)
-
- def raw(self, raw_query, params=None, *args, **kwargs):
- return RawQuerySet(raw_query=raw_query, model=self.model, params=params, using=self._db, *args, **kwargs)
-
Manager = BaseManager.from_queryset(QuerySet, class_name='Manager')
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 63861bb71b..a3e0a9540f 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -413,8 +413,8 @@ class QuerySet(object):
specifying whether an object was created.
"""
lookup, params, _ = self._extract_model_params(defaults, **kwargs)
+ self._for_write = True
try:
- self._for_write = True
return self.get(**lookup), False
except self.model.DoesNotExist:
return self._create_object_from_params(lookup, params)
@@ -427,8 +427,8 @@ class QuerySet(object):
specifying whether an object was created.
"""
lookup, params, filtered_defaults = self._extract_model_params(defaults, **kwargs)
+ self._for_write = True
try:
- self._for_write = True
obj = self.get(**lookup)
except self.model.DoesNotExist:
obj, created = self._create_object_from_params(lookup, params)
@@ -623,6 +623,13 @@ class QuerySet(object):
# PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
##################################################
+ def raw(self, raw_query, params=None, translations=None, using=None):
+ if using is None:
+ using = self.db
+ return RawQuerySet(raw_query, model=self.model,
+ params=params, translations=translations,
+ using=using)
+
def values(self, *fields):
return self._clone(klass=ValuesQuerySet, setup=True, _fields=fields)
@@ -909,6 +916,21 @@ class QuerySet(object):
###################
# PRIVATE METHODS #
###################
+
+ def _insert(self, objs, fields, return_id=False, raw=False, using=None):
+ """
+ Inserts a new record for the given model. This provides an interface to
+ the InsertQuery class and is how Model.save() is implemented.
+ """
+ self._for_write = True
+ if using is None:
+ using = self.db
+ query = sql.InsertQuery(self.model)
+ query.insert_values(fields, objs, raw=raw)
+ return query.get_compiler(using=using).execute_sql(return_id)
+ _insert.alters_data = True
+ _insert.queryset_only = False
+
def _batched_insert(self, objs, fields, batch_size):
"""
A little helper method for bulk_insert to insert the bulk one batch
@@ -1601,17 +1623,6 @@ class RawQuerySet(object):
return self._model_fields
-def insert_query(model, objs, fields, return_id=False, raw=False, using=None):
- """
- Inserts a new record for the given model. This provides an interface to
- the InsertQuery class and is how Model.save() is implemented. It is not
- part of the public API.
- """
- query = sql.InsertQuery(model)
- query.insert_values(fields, objs, raw=raw)
- return query.get_compiler(using=using).execute_sql(return_id)
-
-
def prefetch_related_objects(result_cache, related_lookups):
"""
Helper function for prefetch_related functionality
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index c3f6a660b4..95dad202fa 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -1262,6 +1262,28 @@ unexpectedly blocking.
Using ``select_for_update`` on backends which do not support
``SELECT ... FOR UPDATE`` (such as SQLite) will have no effect.
+raw
+~~~
+
+.. method:: raw(raw_query, params=None, translations=None)
+
+.. versionchanged:: 1.7
+
+ ``raw`` was moved to the ``QuerySet`` class. It was previously only on
+ :class:`~django.db.models.Manager`.
+
+Takes a raw SQL query, executes it, and returns a
+``django.db.models.query.RawQuerySet`` instance. This ``RawQuerySet`` instance
+can be iterated over just like an normal QuerySet to provide object instances.
+
+See the :ref:`executing-raw-queries` for more information.
+
+.. warning::
+
+ ``raw()`` always triggers a new query and doesn't account for previous
+ filtering. As such, it should generally be called from the ``Manager`` or
+ from a fresh ``QuerySet`` instance.
+
Methods that do not return QuerySets
------------------------------------
diff --git a/tests/basic/tests.py b/tests/basic/tests.py
index 879c7869fa..55ed6a436f 100644
--- a/tests/basic/tests.py
+++ b/tests/basic/tests.py
@@ -773,7 +773,9 @@ class ManagerTest(TestCase):
'only',
'using',
'exists',
+ '_insert',
'_update',
+ 'raw',
]
def test_manager_methods(self):