diff --git a/django/db/models/base.py b/django/db/models/base.py index 6c2bd858d4..0d06ca5727 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -315,11 +315,11 @@ class Model(object): update_pk = bool(meta.has_auto_field and not pk_set) if values: # Create a new record. - result = manager._insert(_return_id=update_pk, **dict(values)) + result = manager._insert(__return_id=update_pk, **dict(values)) else: # Create a new record with defaults for everything. - result = manager._insert(_return_id=update_pk, - _raw_values=True, pk=connection.ops.pk_default_value()) + result = manager._insert(__return_id=update_pk, + __raw_values=True, pk=connection.ops.pk_default_value()) if update_pk: setattr(self, meta.pk.attname, result) diff --git a/django/db/models/manager.py b/django/db/models/manager.py index 229232445b..3a2efe84a8 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -1,4 +1,4 @@ -from django.db.models.query import QuerySet, EmptyQuerySet +from django.db.models.query import QuerySet, EmptyQuerySet, insert_query from django.dispatch import dispatcher from django.db.models import signals from django.db.models.fields import FieldDoesNotExist @@ -110,8 +110,8 @@ class Manager(object): def reverse(self, *args, **kwargs): return self.get_query_set().reverse(*args, **kwargs) - def _insert(self, *args, **kwargs): - return self.get_query_set()._insert(*args, **kwargs) + def _insert(self, **kwargs): + return insert_query(self.model, **kwargs) class ManagerDescriptor(object): # This class ensures managers aren't accessible via model instances. diff --git a/django/db/models/query.py b/django/db/models/query.py index 5a82988e3d..57e41fc608 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -457,18 +457,6 @@ class _QuerySet(object): except StopIteration: self._iter = None - def _insert(self, _return_id=False, _raw_values=False, **kwargs): - """ - 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 of QuerySet, though. - """ - self._result_cache = None - query = self.query.clone(sql.InsertQuery) - query.insert_values(kwargs, _raw_values) - return query.execute_sql(_return_id) - _insert.alters_data = True - # Use the backend's QuerySet class if it defines one. Otherwise, use _QuerySet. if connection.features.uses_custom_queryset: QuerySet = connection.ops.query_set_class(_QuerySet) @@ -681,3 +669,13 @@ def delete_objects(seen_objs): transaction.commit_unless_managed() +def insert_query(__model, __return_id=False, __raw_values=False, **kwargs): + """ + 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, connection) + query.insert_values(kwargs, __raw_values) + return query.execute_sql(__return_id) +