Skip to content

Commit

Permalink
Fixed #20826 -- Moved Manager.raw() and Manager._insert() to the Quer…
Browse files Browse the repository at this point in the history
…ySet class.
  • Loading branch information
loic authored and timgraham committed Jul 31, 2013
1 parent a3a59a3 commit acd1d43
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 20 deletions.
8 changes: 1 addition & 7 deletions django/db/models/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
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
Expand Down Expand Up @@ -169,12 +169,6 @@ def all(self):
# 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')


Expand Down
37 changes: 24 additions & 13 deletions django/db/models/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,8 @@ def get_or_create(self, defaults=None, **kwargs):
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)
Expand All @@ -427,8 +427,8 @@ def update_or_create(self, defaults=None, **kwargs):
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)
Expand Down Expand Up @@ -623,6 +623,13 @@ def _prefetch_related_objects(self):
# 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)

Expand Down Expand Up @@ -909,6 +916,21 @@ def db(self):
###################
# 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
Expand Down Expand Up @@ -1601,17 +1623,6 @@ def model_fields(self):
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
Expand Down
22 changes: 22 additions & 0 deletions docs/ref/models/querysets.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------------------------------

Expand Down
2 changes: 2 additions & 0 deletions tests/basic/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,9 @@ class ManagerTest(TestCase):
'only',
'using',
'exists',
'_insert',
'_update',
'raw',
]

def test_manager_methods(self):
Expand Down

0 comments on commit acd1d43

Please sign in to comment.