summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/django/db
diff options
context:
space:
mode:
authorcoderick142017-05-17 15:40:18 +0530
committercoderick142017-05-17 15:41:00 +0530
commitfe407193c200e03070928c1e2c1a6e067d32893d (patch)
tree1c492aa814754b5db5d644c769f5382306217298 /lib/python2.7/site-packages/django/db
parent9a1393e8470d855762e699abca9911b9cdae6a7d (diff)
downloadSBHS-2018-Rpi-fe407193c200e03070928c1e2c1a6e067d32893d.tar.gz
SBHS-2018-Rpi-fe407193c200e03070928c1e2c1a6e067d32893d.tar.bz2
SBHS-2018-Rpi-fe407193c200e03070928c1e2c1a6e067d32893d.zip
Upgrade to Django 1.11
- Database integration yet to be tested
Diffstat (limited to 'lib/python2.7/site-packages/django/db')
-rw-r--r--lib/python2.7/site-packages/django/db/__init__.py96
-rw-r--r--lib/python2.7/site-packages/django/db/backends/__init__.py1356
-rw-r--r--lib/python2.7/site-packages/django/db/backends/creation.py489
-rw-r--r--lib/python2.7/site-packages/django/db/backends/dummy/__init__.py0
-rw-r--r--lib/python2.7/site-packages/django/db/backends/dummy/base.py73
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/__init__.py0
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/base.py533
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/client.py40
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/compiler.py37
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/creation.py70
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/introspection.py119
-rw-r--r--lib/python2.7/site-packages/django/db/backends/mysql/validation.py16
-rw-r--r--lib/python2.7/site-packages/django/db/backends/oracle/__init__.py0
-rw-r--r--lib/python2.7/site-packages/django/db/backends/oracle/base.py961
-rw-r--r--lib/python2.7/site-packages/django/db/backends/oracle/client.py16
-rw-r--r--lib/python2.7/site-packages/django/db/backends/oracle/compiler.py72
-rw-r--r--lib/python2.7/site-packages/django/db/backends/oracle/creation.py277
-rw-r--r--lib/python2.7/site-packages/django/db/backends/oracle/introspection.py138
-rw-r--r--lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/__init__.py0
-rw-r--r--lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py184
-rw-r--r--lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/client.py23
-rw-r--r--lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/creation.py77
-rw-r--r--lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/introspection.py111
-rw-r--r--lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/operations.py222
-rw-r--r--lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/version.py43
-rw-r--r--lib/python2.7/site-packages/django/db/backends/signals.py3
-rw-r--r--lib/python2.7/site-packages/django/db/backends/sqlite3/__init__.py0
-rw-r--r--lib/python2.7/site-packages/django/db/backends/sqlite3/base.py533
-rw-r--r--lib/python2.7/site-packages/django/db/backends/sqlite3/client.py16
-rw-r--r--lib/python2.7/site-packages/django/db/backends/sqlite3/creation.py88
-rw-r--r--lib/python2.7/site-packages/django/db/backends/sqlite3/introspection.py185
-rw-r--r--lib/python2.7/site-packages/django/db/backends/util.py179
-rw-r--r--lib/python2.7/site-packages/django/db/models/__init__.py33
-rw-r--r--lib/python2.7/site-packages/django/db/models/aggregates.py80
-rw-r--r--lib/python2.7/site-packages/django/db/models/base.py1042
-rw-r--r--lib/python2.7/site-packages/django/db/models/constants.py6
-rw-r--r--lib/python2.7/site-packages/django/db/models/deletion.py292
-rw-r--r--lib/python2.7/site-packages/django/db/models/expressions.py186
-rw-r--r--lib/python2.7/site-packages/django/db/models/fields/__init__.py1438
-rw-r--r--lib/python2.7/site-packages/django/db/models/fields/files.py397
-rw-r--r--lib/python2.7/site-packages/django/db/models/fields/proxy.py17
-rw-r--r--lib/python2.7/site-packages/django/db/models/fields/related.py1545
-rw-r--r--lib/python2.7/site-packages/django/db/models/fields/subclassing.py53
-rw-r--r--lib/python2.7/site-packages/django/db/models/loading.py327
-rw-r--r--lib/python2.7/site-packages/django/db/models/manager.py283
-rw-r--r--lib/python2.7/site-packages/django/db/models/options.py589
-rw-r--r--lib/python2.7/site-packages/django/db/models/query.py1731
-rw-r--r--lib/python2.7/site-packages/django/db/models/query_utils.py205
-rw-r--r--lib/python2.7/site-packages/django/db/models/related.py67
-rw-r--r--lib/python2.7/site-packages/django/db/models/signals.py18
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/__init__.py9
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/aggregates.py125
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/compiler.py1128
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/constants.py41
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/datastructures.py62
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/expressions.py117
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/query.py1922
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/subqueries.py297
-rw-r--r--lib/python2.7/site-packages/django/db/models/sql/where.py419
-rw-r--r--lib/python2.7/site-packages/django/db/transaction.py541
-rw-r--r--lib/python2.7/site-packages/django/db/utils.py282
61 files changed, 0 insertions, 19209 deletions
diff --git a/lib/python2.7/site-packages/django/db/__init__.py b/lib/python2.7/site-packages/django/db/__init__.py
deleted file mode 100644
index 2421dde..0000000
--- a/lib/python2.7/site-packages/django/db/__init__.py
+++ /dev/null
@@ -1,96 +0,0 @@
-import warnings
-
-from django.core import signals
-from django.db.utils import (DEFAULT_DB_ALIAS,
- DataError, OperationalError, IntegrityError, InternalError,
- ProgrammingError, NotSupportedError, DatabaseError,
- InterfaceError, Error,
- load_backend, ConnectionHandler, ConnectionRouter)
-from django.utils.functional import cached_property
-
-__all__ = ('backend', 'connection', 'connections', 'router', 'DatabaseError',
- 'IntegrityError', 'DEFAULT_DB_ALIAS')
-
-connections = ConnectionHandler()
-
-router = ConnectionRouter()
-
-# `connection`, `DatabaseError` and `IntegrityError` are convenient aliases
-# for backend bits.
-
-# DatabaseWrapper.__init__() takes a dictionary, not a settings module, so
-# we manually create the dictionary from the settings, passing only the
-# settings that the database backends care about. Note that TIME_ZONE is used
-# by the PostgreSQL backends.
-# We load all these up for backwards compatibility, you should use
-# connections['default'] instead.
-class DefaultConnectionProxy(object):
- """
- Proxy for accessing the default DatabaseWrapper object's attributes. If you
- need to access the DatabaseWrapper object itself, use
- connections[DEFAULT_DB_ALIAS] instead.
- """
- def __getattr__(self, item):
- return getattr(connections[DEFAULT_DB_ALIAS], item)
-
- def __setattr__(self, name, value):
- return setattr(connections[DEFAULT_DB_ALIAS], name, value)
-
- def __delattr__(self, name):
- return delattr(connections[DEFAULT_DB_ALIAS], name)
-
-connection = DefaultConnectionProxy()
-
-class DefaultBackendProxy(object):
- """
- Temporary proxy class used during deprecation period of the `backend` module
- variable.
- """
- @cached_property
- def _backend(self):
- warnings.warn("Accessing django.db.backend is deprecated.",
- PendingDeprecationWarning, stacklevel=2)
- return load_backend(connections[DEFAULT_DB_ALIAS].settings_dict['ENGINE'])
-
- def __getattr__(self, item):
- return getattr(self._backend, item)
-
- def __setattr__(self, name, value):
- return setattr(self._backend, name, value)
-
- def __delattr__(self, name):
- return delattr(self._backend, name)
-
-backend = DefaultBackendProxy()
-
-def close_connection(**kwargs):
- warnings.warn(
- "close_connection is superseded by close_old_connections.",
- PendingDeprecationWarning, stacklevel=2)
- # Avoid circular imports
- from django.db import transaction
- for conn in connections:
- # If an error happens here the connection will be left in broken
- # state. Once a good db connection is again available, the
- # connection state will be cleaned up.
- transaction.abort(conn)
- connections[conn].close()
-
-# Register an event to reset saved queries when a Django request is started.
-def reset_queries(**kwargs):
- for conn in connections.all():
- conn.queries = []
-signals.request_started.connect(reset_queries)
-
-# Register an event to reset transaction state and close connections past
-# their lifetime. NB: abort() doesn't do anything outside of a transaction.
-def close_old_connections(**kwargs):
- for conn in connections.all():
- # Remove this when the legacy transaction management goes away.
- try:
- conn.abort()
- except DatabaseError:
- pass
- conn.close_if_unusable_or_obsolete()
-signals.request_started.connect(close_old_connections)
-signals.request_finished.connect(close_old_connections)
diff --git a/lib/python2.7/site-packages/django/db/backends/__init__.py b/lib/python2.7/site-packages/django/db/backends/__init__.py
deleted file mode 100644
index 12f08a2..0000000
--- a/lib/python2.7/site-packages/django/db/backends/__init__.py
+++ /dev/null
@@ -1,1356 +0,0 @@
-import datetime
-import time
-
-from django.db.utils import DatabaseError
-
-try:
- from django.utils.six.moves import _thread as thread
-except ImportError:
- from django.utils.six.moves import _dummy_thread as thread
-from collections import namedtuple
-from contextlib import contextmanager
-
-from django.conf import settings
-from django.db import DEFAULT_DB_ALIAS
-from django.db.backends.signals import connection_created
-from django.db.backends import util
-from django.db.transaction import TransactionManagementError
-from django.db.utils import DatabaseErrorWrapper
-from django.utils.functional import cached_property
-from django.utils.importlib import import_module
-from django.utils import six
-from django.utils import timezone
-
-
-class BaseDatabaseWrapper(object):
- """
- Represents a database connection.
- """
- ops = None
- vendor = 'unknown'
-
- def __init__(self, settings_dict, alias=DEFAULT_DB_ALIAS,
- allow_thread_sharing=False):
- # `settings_dict` should be a dictionary containing keys such as
- # NAME, USER, etc. It's called `settings_dict` instead of `settings`
- # to disambiguate it from Django settings modules.
- self.connection = None
- self.queries = []
- self.settings_dict = settings_dict
- self.alias = alias
- self.use_debug_cursor = None
-
- # Savepoint management related attributes
- self.savepoint_state = 0
-
- # Transaction management related attributes
- self.autocommit = False
- self.transaction_state = []
- # Tracks if the connection is believed to be in transaction. This is
- # set somewhat aggressively, as the DBAPI doesn't make it easy to
- # deduce if the connection is in transaction or not.
- self._dirty = False
- # Tracks if the connection is in a transaction managed by 'atomic'.
- self.in_atomic_block = False
- # List of savepoints created by 'atomic'
- self.savepoint_ids = []
- # Tracks if the outermost 'atomic' block should commit on exit,
- # ie. if autocommit was active on entry.
- self.commit_on_exit = True
- # Tracks if the transaction should be rolled back to the next
- # available savepoint because of an exception in an inner block.
- self.needs_rollback = False
-
- # Connection termination related attributes
- self.close_at = None
- self.closed_in_transaction = False
- self.errors_occurred = False
-
- # Thread-safety related attributes
- self.allow_thread_sharing = allow_thread_sharing
- self._thread_ident = thread.get_ident()
-
- def __eq__(self, other):
- return self.alias == other.alias
-
- def __ne__(self, other):
- return not self == other
-
- def __hash__(self):
- return hash(self.alias)
-
- ##### Backend-specific methods for creating connections and cursors #####
-
- def get_connection_params(self):
- """Returns a dict of parameters suitable for get_new_connection."""
- raise NotImplementedError
-
- def get_new_connection(self, conn_params):
- """Opens a connection to the database."""
- raise NotImplementedError
-
- def init_connection_state(self):
- """Initializes the database connection settings."""
- raise NotImplementedError
-
- def create_cursor(self):
- """Creates a cursor. Assumes that a connection is established."""
- raise NotImplementedError
-
- ##### Backend-specific methods for creating connections #####
-
- def connect(self):
- """Connects to the database. Assumes that the connection is closed."""
- # In case the previous connection was closed while in an atomic block
- self.in_atomic_block = False
- self.savepoint_ids = []
- self.needs_rollback = False
- # Reset parameters defining when to close the connection
- max_age = self.settings_dict['CONN_MAX_AGE']
- self.close_at = None if max_age is None else time.time() + max_age
- self.closed_in_transaction = False
- self.errors_occurred = False
- # Establish the connection
- conn_params = self.get_connection_params()
- self.connection = self.get_new_connection(conn_params)
- self.init_connection_state()
- if self.settings_dict['AUTOCOMMIT']:
- self.set_autocommit(True)
- connection_created.send(sender=self.__class__, connection=self)
-
- def ensure_connection(self):
- """
- Guarantees that a connection to the database is established.
- """
- if self.connection is None:
- with self.wrap_database_errors:
- self.connect()
-
- ##### Backend-specific wrappers for PEP-249 connection methods #####
-
- def _cursor(self):
- self.ensure_connection()
- with self.wrap_database_errors:
- return self.create_cursor()
-
- def _commit(self):
- if self.connection is not None:
- with self.wrap_database_errors:
- return self.connection.commit()
-
- def _rollback(self):
- if self.connection is not None:
- with self.wrap_database_errors:
- return self.connection.rollback()
-
- def _close(self):
- if self.connection is not None:
- with self.wrap_database_errors:
- return self.connection.close()
-
- ##### Generic wrappers for PEP-249 connection methods #####
-
- def cursor(self):
- """
- Creates a cursor, opening a connection if necessary.
- """
- self.validate_thread_sharing()
- if (self.use_debug_cursor or
- (self.use_debug_cursor is None and settings.DEBUG)):
- cursor = self.make_debug_cursor(self._cursor())
- else:
- cursor = util.CursorWrapper(self._cursor(), self)
- return cursor
-
- def commit(self):
- """
- Commits a transaction and resets the dirty flag.
- """
- self.validate_thread_sharing()
- self.validate_no_atomic_block()
- self._commit()
- self.set_clean()
-
- def rollback(self):
- """
- Rolls back a transaction and resets the dirty flag.
- """
- self.validate_thread_sharing()
- self.validate_no_atomic_block()
- self._rollback()
- self.set_clean()
-
- def close(self):
- """
- Closes the connection to the database.
- """
- self.validate_thread_sharing()
- # Don't call validate_no_atomic_block() to avoid making it difficult
- # to get rid of a connection in an invalid state. The next connect()
- # will reset the transaction state anyway.
- try:
- self._close()
- finally:
- if self.in_atomic_block:
- self.closed_in_transaction = True
- self.needs_rollback = True
- else:
- self.connection = None
- self.set_clean()
-
- ##### Backend-specific savepoint management methods #####
-
- def _savepoint(self, sid):
- self.cursor().execute(self.ops.savepoint_create_sql(sid))
-
- def _savepoint_rollback(self, sid):
- self.cursor().execute(self.ops.savepoint_rollback_sql(sid))
-
- def _savepoint_commit(self, sid):
- self.cursor().execute(self.ops.savepoint_commit_sql(sid))
-
- def _savepoint_allowed(self):
- # Savepoints cannot be created outside a transaction
- return self.features.uses_savepoints and not self.get_autocommit()
-
- ##### Generic savepoint management methods #####
-
- def savepoint(self):
- """
- Creates a savepoint inside the current transaction. Returns an
- identifier for the savepoint that will be used for the subsequent
- rollback or commit. Does nothing if savepoints are not supported.
- """
- if not self._savepoint_allowed():
- return
-
- thread_ident = thread.get_ident()
- tid = str(thread_ident).replace('-', '')
-
- self.savepoint_state += 1
- sid = "s%s_x%d" % (tid, self.savepoint_state)
-
- self.validate_thread_sharing()
- self._savepoint(sid)
-
- return sid
-
- def savepoint_rollback(self, sid):
- """
- Rolls back to a savepoint. Does nothing if savepoints are not supported.
- """
- if not self._savepoint_allowed():
- return
-
- self.validate_thread_sharing()
- self._savepoint_rollback(sid)
-
- def savepoint_commit(self, sid):
- """
- Releases a savepoint. Does nothing if savepoints are not supported.
- """
- if not self._savepoint_allowed():
- return
-
- self.validate_thread_sharing()
- self._savepoint_commit(sid)
-
- def clean_savepoints(self):
- """
- Resets the counter used to generate unique savepoint ids in this thread.
- """
- self.savepoint_state = 0
-
- ##### Backend-specific transaction management methods #####
-
- def _set_autocommit(self, autocommit):
- """
- Backend-specific implementation to enable or disable autocommit.
- """
- raise NotImplementedError
-
- ##### Generic transaction management methods #####
-
- def enter_transaction_management(self, managed=True, forced=False):
- """
- Enters transaction management for a running thread. It must be balanced with
- the appropriate leave_transaction_management call, since the actual state is
- managed as a stack.
-
- The state and dirty flag are carried over from the surrounding block or
- from the settings, if there is no surrounding block (dirty is always false
- when no current block is running).
-
- If you switch off transaction management and there is a pending
- commit/rollback, the data will be commited, unless "forced" is True.
- """
- self.validate_no_atomic_block()
-
- self.transaction_state.append(managed)
-
- if not managed and self.is_dirty() and not forced:
- self.commit()
- self.set_clean()
-
- if managed == self.get_autocommit():
- self.set_autocommit(not managed)
-
- def leave_transaction_management(self):
- """
- Leaves transaction management for a running thread. A dirty flag is carried
- over to the surrounding block, as a commit will commit all changes, even
- those from outside. (Commits are on connection level.)
- """
- self.validate_no_atomic_block()
-
- if self.transaction_state:
- del self.transaction_state[-1]
- else:
- raise TransactionManagementError(
- "This code isn't under transaction management")
-
- if self.transaction_state:
- managed = self.transaction_state[-1]
- else:
- managed = not self.settings_dict['AUTOCOMMIT']
-
- if self._dirty:
- self.rollback()
- if managed == self.get_autocommit():
- self.set_autocommit(not managed)
- raise TransactionManagementError(
- "Transaction managed block ended with pending COMMIT/ROLLBACK")
-
- if managed == self.get_autocommit():
- self.set_autocommit(not managed)
-
- def get_autocommit(self):
- """
- Check the autocommit state.
- """
- self.ensure_connection()
- return self.autocommit
-
- def set_autocommit(self, autocommit):
- """
- Enable or disable autocommit.
- """
- self.validate_no_atomic_block()
- self.ensure_connection()
- self._set_autocommit(autocommit)
- self.autocommit = autocommit
-
- def get_rollback(self):
- """
- Get the "needs rollback" flag -- for *advanced use* only.
- """
- if not self.in_atomic_block:
- raise TransactionManagementError(
- "The rollback flag doesn't work outside of an 'atomic' block.")
- return self.needs_rollback
-
- def set_rollback(self, rollback):
- """
- Set or unset the "needs rollback" flag -- for *advanced use* only.
- """
- if not self.in_atomic_block:
- raise TransactionManagementError(
- "The rollback flag doesn't work outside of an 'atomic' block.")
- self.needs_rollback = rollback
-
- def validate_no_atomic_block(self):
- """
- Raise an error if an atomic block is active.
- """
- if self.in_atomic_block:
- raise TransactionManagementError(
- "This is forbidden when an 'atomic' block is active.")
-
- def validate_no_broken_transaction(self):
- if self.needs_rollback:
- raise TransactionManagementError(
- "An error occurred in the current transaction. You can't "
- "execute queries until the end of the 'atomic' block.")
-
- def abort(self):
- """
- Roll back any ongoing transaction and clean the transaction state
- stack.
- """
- if self._dirty:
- self.rollback()
- while self.transaction_state:
- self.leave_transaction_management()
-
- def is_dirty(self):
- """
- Returns True if the current transaction requires a commit for changes to
- happen.
- """
- return self._dirty
-
- def set_dirty(self):
- """
- Sets a dirty flag for the current thread and code streak. This can be used
- to decide in a managed block of code to decide whether there are open
- changes waiting for commit.
- """
- if not self.get_autocommit():
- self._dirty = True
-
- def set_clean(self):
- """
- Resets a dirty flag for the current thread and code streak. This can be used
- to decide in a managed block of code to decide whether a commit or rollback
- should happen.
- """
- self._dirty = False
- self.clean_savepoints()
-
- ##### Foreign key constraints checks handling #####
-
- @contextmanager
- def constraint_checks_disabled(self):
- """
- Context manager that disables foreign key constraint checking.
- """
- disabled = self.disable_constraint_checking()
- try:
- yield
- finally:
- if disabled:
- self.enable_constraint_checking()
-
- def disable_constraint_checking(self):
- """
- Backends can implement as needed to temporarily disable foreign key
- constraint checking. Should return True if the constraints were
- disabled and will need to be reenabled.
- """
- return False
-
- def enable_constraint_checking(self):
- """
- Backends can implement as needed to re-enable foreign key constraint
- checking.
- """
- pass
-
- def check_constraints(self, table_names=None):
- """
- Backends can override this method if they can apply constraint
- checking (e.g. via "SET CONSTRAINTS ALL IMMEDIATE"). Should raise an
- IntegrityError if any invalid foreign key references are encountered.
- """
- pass
-
- ##### Connection termination handling #####
-
- def is_usable(self):
- """
- Tests if the database connection is usable.
-
- This function may assume that self.connection is not None.
-
- Actual implementations should take care not to raise exceptions
- as that may prevent Django from recycling unusable connections.
- """
- raise NotImplementedError(
- "subclasses of BaseDatabaseWrapper may require an is_usable() method")
-
- def close_if_unusable_or_obsolete(self):
- """
- Closes the current connection if unrecoverable errors have occurred,
- or if it outlived its maximum age.
- """
- if self.connection is not None:
- # If the application didn't restore the original autocommit setting,
- # don't take chances, drop the connection.
- if self.get_autocommit() != self.settings_dict['AUTOCOMMIT']:
- self.close()
- return
-
- if self.errors_occurred:
- if self.is_usable():
- self.errors_occurred = False
- else:
- self.close()
- return
-
- if self.close_at is not None and time.time() >= self.close_at:
- self.close()
- return
-
- ##### Thread safety handling #####
-
- def validate_thread_sharing(self):
- """
- Validates that the connection isn't accessed by another thread than the
- one which originally created it, unless the connection was explicitly
- authorized to be shared between threads (via the `allow_thread_sharing`
- property). Raises an exception if the validation fails.
- """
- if not (self.allow_thread_sharing
- or self._thread_ident == thread.get_ident()):
- raise DatabaseError("DatabaseWrapper objects created in a "
- "thread can only be used in that same thread. The object "
- "with alias '%s' was created in thread id %s and this is "
- "thread id %s."
- % (self.alias, self._thread_ident, thread.get_ident()))
-
- ##### Miscellaneous #####
-
- @cached_property
- def wrap_database_errors(self):
- """
- Context manager and decorator that re-throws backend-specific database
- exceptions using Django's common wrappers.
- """
- return DatabaseErrorWrapper(self)
-
- def make_debug_cursor(self, cursor):
- """
- Creates a cursor that logs all queries in self.queries.
- """
- return util.CursorDebugWrapper(cursor, self)
-
- @contextmanager
- def temporary_connection(self):
- """
- Context manager that ensures that a connection is established, and
- if it opened one, closes it to avoid leaving a dangling connection.
- This is useful for operations outside of the request-response cycle.
-
- Provides a cursor: with self.temporary_connection() as cursor: ...
- """
- must_close = self.connection is None
- cursor = self.cursor()
- try:
- yield cursor
- finally:
- cursor.close()
- if must_close:
- self.close()
-
- def _start_transaction_under_autocommit(self):
- """
- Only required when autocommits_when_autocommit_is_off = True.
- """
- raise NotImplementedError
-
-
-class BaseDatabaseFeatures(object):
- allows_group_by_pk = False
- # True if django.db.backend.utils.typecast_timestamp is used on values
- # returned from dates() calls.
- needs_datetime_string_cast = True
- empty_fetchmany_value = []
- update_can_self_select = True
-
- # Does the backend distinguish between '' and None?
- interprets_empty_strings_as_nulls = False
-
- # Does the backend allow inserting duplicate rows when a unique_together
- # constraint exists, but one of the unique_together columns is NULL?
- ignores_nulls_in_unique_constraints = True
-
- can_use_chunked_reads = True
- can_return_id_from_insert = False
- has_bulk_insert = False
- uses_savepoints = False
- can_combine_inserts_with_and_without_auto_increment_pk = False
-
- # If True, don't use integer foreign keys referring to, e.g., positive
- # integer primary keys.
- related_fields_match_type = False
- allow_sliced_subqueries = True
- has_select_for_update = False
- has_select_for_update_nowait = False
-
- supports_select_related = True
-
- # Does the default test database allow multiple connections?
- # Usually an indication that the test database is in-memory
- test_db_allows_multiple_connections = True
-
- # Can an object be saved without an explicit primary key?
- supports_unspecified_pk = False
-
- # Can a fixture contain forward references? i.e., are
- # FK constraints checked at the end of transaction, or
- # at the end of each save operation?
- supports_forward_references = True
-
- # Does a dirty transaction need to be rolled back
- # before the cursor can be used again?
- requires_rollback_on_dirty_transaction = False
-
- # Does the backend allow very long model names without error?
- supports_long_model_names = True
-
- # Is there a REAL datatype in addition to floats/doubles?
- has_real_datatype = False
- supports_subqueries_in_group_by = True
- supports_bitwise_or = True
-
- # Do time/datetime fields have microsecond precision?
- supports_microsecond_precision = True
-
- # Does the __regex lookup support backreferencing and grouping?
- supports_regex_backreferencing = True
-
- # Can date/datetime lookups be performed using a string?
- supports_date_lookup_using_string = True
-
- # Can datetimes with timezones be used?
- supports_timezones = True
-
- # Does the database have a copy of the zoneinfo database?
- has_zoneinfo_database = True
-
- # When performing a GROUP BY, is an ORDER BY NULL required
- # to remove any ordering?
- requires_explicit_null_ordering_when_grouping = False
-
- # Is there a 1000 item limit on query parameters?
- supports_1000_query_parameters = True
-
- # Can an object have a primary key of 0? MySQL says No.
- allows_primary_key_0 = True
-
- # Do we need to NULL a ForeignKey out, or can the constraint check be
- # deferred
- can_defer_constraint_checks = False
-
- # date_interval_sql can properly handle mixed Date/DateTime fields and timedeltas
- supports_mixed_date_datetime_comparisons = True
-
- # Does the backend support tablespaces? Default to False because it isn't
- # in the SQL standard.
- supports_tablespaces = False
-
- # Does the backend reset sequences between tests?
- supports_sequence_reset = True
-
- # Confirm support for introspected foreign keys
- # Every database can do this reliably, except MySQL,
- # which can't do it for MyISAM tables
- can_introspect_foreign_keys = True
-
- # Support for the DISTINCT ON clause
- can_distinct_on_fields = False
-
- # Does the backend decide to commit before SAVEPOINT statements
- # when autocommit is disabled? http://bugs.python.org/issue8145#msg109965
- autocommits_when_autocommit_is_off = False
-
- # Does the backend prevent running SQL queries in broken transactions?
- atomic_transactions = True
-
- # Does the backend support 'pyformat' style ("... %(name)s ...", {'name': value})
- # parameter passing? Note this can be provided by the backend even if not
- # supported by the Python driver
- supports_paramstyle_pyformat = True
-
- def __init__(self, connection):
- self.connection = connection
-
- @cached_property
- def supports_transactions(self):
- "Confirm support for transactions"
- try:
- # Make sure to run inside a managed transaction block,
- # otherwise autocommit will cause the confimation to
- # fail.
- self.connection.enter_transaction_management()
- cursor = self.connection.cursor()
- cursor.execute('CREATE TABLE ROLLBACK_TEST (X INT)')
- self.connection.commit()
- cursor.execute('INSERT INTO ROLLBACK_TEST (X) VALUES (8)')
- self.connection.rollback()
- cursor.execute('SELECT COUNT(X) FROM ROLLBACK_TEST')
- count, = cursor.fetchone()
- cursor.execute('DROP TABLE ROLLBACK_TEST')
- self.connection.commit()
- finally:
- self.connection.leave_transaction_management()
- return count == 0
-
- @cached_property
- def supports_stddev(self):
- "Confirm support for STDDEV and related stats functions"
- class StdDevPop(object):
- sql_function = 'STDDEV_POP'
-
- try:
- self.connection.ops.check_aggregate_support(StdDevPop())
- return True
- except NotImplementedError:
- return False
-
-
-class BaseDatabaseOperations(object):
- """
- This class encapsulates all backend-specific differences, such as the way
- a backend performs ordering or calculates the ID of a recently-inserted
- row.
- """
- compiler_module = "django.db.models.sql.compiler"
-
- def __init__(self, connection):
- self.connection = connection
- self._cache = None
-
- def autoinc_sql(self, table, column):
- """
- Returns any SQL needed to support auto-incrementing primary keys, or
- None if no SQL is necessary.
-
- This SQL is executed when a table is created.
- """
- return None
-
- def bulk_batch_size(self, fields, objs):
- """
- Returns the maximum allowed batch size for the backend. The fields
- are the fields going to be inserted in the batch, the objs contains
- all the objects to be inserted.
- """
- return len(objs)
-
- def cache_key_culling_sql(self):
- """
- Returns an SQL query that retrieves the first cache key greater than the
- n smallest.
-
- This is used by the 'db' cache backend to determine where to start
- culling.
- """
- return "SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s"
-
- def date_extract_sql(self, lookup_type, field_name):
- """
- Given a lookup_type of 'year', 'month' or 'day', returns the SQL that
- extracts a value from the given date field field_name.
- """
- raise NotImplementedError()
-
- def date_interval_sql(self, sql, connector, timedelta):
- """
- Implements the date interval functionality for expressions
- """
- raise NotImplementedError()
-
- def date_trunc_sql(self, lookup_type, field_name):
- """
- Given a lookup_type of 'year', 'month' or 'day', returns the SQL that
- truncates the given date field field_name to a date object with only
- the given specificity.
- """
- raise NotImplementedError()
-
- def datetime_cast_sql(self):
- """
- Returns the SQL necessary to cast a datetime value so that it will be
- retrieved as a Python datetime object instead of a string.
-
- This SQL should include a '%s' in place of the field's name.
- """
- return "%s"
-
- def datetime_extract_sql(self, lookup_type, field_name, tzname):
- """
- Given a lookup_type of 'year', 'month', 'day', 'hour', 'minute' or
- 'second', returns the SQL that extracts a value from the given
- datetime field field_name, and a tuple of parameters.
- """
- raise NotImplementedError()
-
- def datetime_trunc_sql(self, lookup_type, field_name, tzname):
- """
- Given a lookup_type of 'year', 'month', 'day', 'hour', 'minute' or
- 'second', returns the SQL that truncates the given datetime field
- field_name to a datetime object with only the given specificity, and
- a tuple of parameters.
- """
- raise NotImplementedError()
-
- def deferrable_sql(self):
- """
- Returns the SQL necessary to make a constraint "initially deferred"
- during a CREATE TABLE statement.
- """
- return ''
-
- def distinct_sql(self, fields):
- """
- Returns an SQL DISTINCT clause which removes duplicate rows from the
- result set. If any fields are given, only the given fields are being
- checked for duplicates.
- """
- if fields:
- raise NotImplementedError('DISTINCT ON fields is not supported by this database backend')
- else:
- return 'DISTINCT'
-
- def drop_foreignkey_sql(self):
- """
- Returns the SQL command that drops a foreign key.
- """
- return "DROP CONSTRAINT"
-
- def drop_sequence_sql(self, table):
- """
- Returns any SQL necessary to drop the sequence for the given table.
- Returns None if no SQL is necessary.
- """
- return None
-
- def fetch_returned_insert_id(self, cursor):
- """
- Given a cursor object that has just performed an INSERT...RETURNING
- statement into a table that has an auto-incrementing ID, returns the
- newly created ID.
- """
- return cursor.fetchone()[0]
-
- def field_cast_sql(self, db_type, internal_type):
- """
- Given a column type (e.g. 'BLOB', 'VARCHAR'), and an internal type
- (e.g. 'GenericIPAddressField'), returns the SQL necessary to cast it
- before using it in a WHERE statement. Note that the resulting string
- should contain a '%s' placeholder for the column being searched against.
- """
- return '%s'
-
- def force_no_ordering(self):
- """
- Returns a list used in the "ORDER BY" clause to force no ordering at
- all. Returning an empty list means that nothing will be included in the
- ordering.
- """
- return []
-
- def for_update_sql(self, nowait=False):
- """
- Returns the FOR UPDATE SQL clause to lock rows for an update operation.
- """
- if nowait:
- return 'FOR UPDATE NOWAIT'
- else:
- return 'FOR UPDATE'
-
- def fulltext_search_sql(self, field_name):
- """
- Returns the SQL WHERE clause to use in order to perform a full-text
- search of the given field_name. Note that the resulting string should
- contain a '%s' placeholder for the value being searched against.
- """
- raise NotImplementedError('Full-text search is not implemented for this database backend')
-
- def last_executed_query(self, cursor, sql, params):
- """
- Returns a string of the query last executed by the given cursor, with
- placeholders replaced with actual values.
-
- `sql` is the raw query containing placeholders, and `params` is the
- sequence of parameters. These are used by default, but this method
- exists for database backends to provide a better implementation
- according to their own quoting schemes.
- """
- from django.utils.encoding import force_text
-
- # Convert params to contain Unicode values.
- to_unicode = lambda s: force_text(s, strings_only=True, errors='replace')
- if isinstance(params, (list, tuple)):
- u_params = tuple(to_unicode(val) for val in params)
- elif params is None:
- u_params = ()
- else:
- u_params = dict((to_unicode(k), to_unicode(v)) for k, v in params.items())
-
- return six.text_type("QUERY = %r - PARAMS = %r") % (sql, u_params)
-
- def last_insert_id(self, cursor, table_name, pk_name):
- """
- Given a cursor object that has just performed an INSERT statement into
- a table that has an auto-incrementing ID, returns the newly created ID.
-
- This method also receives the table name and the name of the primary-key
- column.
- """
- return cursor.lastrowid
-
- def lookup_cast(self, lookup_type):
- """
- Returns the string to use in a query when performing lookups
- ("contains", "like", etc). The resulting string should contain a '%s'
- placeholder for the column being searched against.
- """
- return "%s"
-
- def max_in_list_size(self):
- """
- Returns the maximum number of items that can be passed in a single 'IN'
- list condition, or None if the backend does not impose a limit.
- """
- return None
-
- def max_name_length(self):
- """
- Returns the maximum length of table and column names, or None if there
- is no limit.
- """
- return None
-
- def no_limit_value(self):
- """
- Returns the value to use for the LIMIT when we are wanting "LIMIT
- infinity". Returns None if the limit clause can be omitted in this case.
- """
- raise NotImplementedError
-
- def pk_default_value(self):
- """
- Returns the value to use during an INSERT statement to specify that
- the field should use its default value.
- """
- return 'DEFAULT'
-
- def process_clob(self, value):
- """
- Returns the value of a CLOB column, for backends that return a locator
- object that requires additional processing.
- """
- return value
-
- def return_insert_id(self):
- """
- For backends that support returning the last insert ID as part
- of an insert query, this method returns the SQL and params to
- append to the INSERT query. The returned fragment should
- contain a format string to hold the appropriate column.
- """
- pass
-
- def compiler(self, compiler_name):
- """
- Returns the SQLCompiler class corresponding to the given name,
- in the namespace corresponding to the `compiler_module` attribute
- on this backend.
- """
- if self._cache is None:
- self._cache = import_module(self.compiler_module)
- return getattr(self._cache, compiler_name)
-
- def quote_name(self, name):
- """
- Returns a quoted version of the given table, index or column name. Does
- not quote the given name if it's already been quoted.
- """
- raise NotImplementedError()
-
- def random_function_sql(self):
- """
- Returns an SQL expression that returns a random value.
- """
- return 'RANDOM()'
-
- def regex_lookup(self, lookup_type):
- """
- Returns the string to use in a query when performing regular expression
- lookups (using "regex" or "iregex"). The resulting string should
- contain a '%s' placeholder for the column being searched against.
-
- If the feature is not supported (or part of it is not supported), a
- NotImplementedError exception can be raised.
- """
- raise NotImplementedError
-
- def savepoint_create_sql(self, sid):
- """
- Returns the SQL for starting a new savepoint. Only required if the
- "uses_savepoints" feature is True. The "sid" parameter is a string
- for the savepoint id.
- """
- return "SAVEPOINT %s" % self.quote_name(sid)
-
- def savepoint_commit_sql(self, sid):
- """
- Returns the SQL for committing the given savepoint.
- """
- return "RELEASE SAVEPOINT %s" % self.quote_name(sid)
-
- def savepoint_rollback_sql(self, sid):
- """
- Returns the SQL for rolling back the given savepoint.
- """
- return "ROLLBACK TO SAVEPOINT %s" % self.quote_name(sid)
-
- def set_time_zone_sql(self):
- """
- Returns the SQL that will set the connection's time zone.
-
- Returns '' if the backend doesn't support time zones.
- """
- return ''
-
- def sql_flush(self, style, tables, sequences, allow_cascade=False):
- """
- Returns a list of SQL statements required to remove all data from
- the given database tables (without actually removing the tables
- themselves).
-
- The returned value also includes SQL statements required to reset DB
- sequences passed in :param sequences:.
-
- The `style` argument is a Style object as returned by either
- color_style() or no_style() in django.core.management.color.
-
- The `allow_cascade` argument determines whether truncation may cascade
- to tables with foreign keys pointing the tables being truncated.
- PostgreSQL requires a cascade even if these tables are empty.
- """
- raise NotImplementedError()
-
- def sequence_reset_by_name_sql(self, style, sequences):
- """
- Returns a list of the SQL statements required to reset sequences
- passed in :param sequences:.
-
- The `style` argument is a Style object as returned by either
- color_style() or no_style() in django.core.management.color.
- """
- return []
-
- def sequence_reset_sql(self, style, model_list):
- """
- Returns a list of the SQL statements required to reset sequences for
- the given models.
-
- The `style` argument is a Style object as returned by either
- color_style() or no_style() in django.core.management.color.
- """
- return [] # No sequence reset required by default.
-
- def start_transaction_sql(self):
- """
- Returns the SQL statement required to start a transaction.
- """
- return "BEGIN;"
-
- def end_transaction_sql(self, success=True):
- """
- Returns the SQL statement required to end a transaction.
- """
- if not success:
- return "ROLLBACK;"
- return "COMMIT;"
-
- def tablespace_sql(self, tablespace, inline=False):
- """
- Returns the SQL that will be used in a query to define the tablespace.
-
- Returns '' if the backend doesn't support tablespaces.
-
- If inline is True, the SQL is appended to a row; otherwise it's appended
- to the entire CREATE TABLE or CREATE INDEX statement.
- """
- return ''
-
- def prep_for_like_query(self, x):
- """Prepares a value for use in a LIKE query."""
- from django.utils.encoding import force_text
- return force_text(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
-
- # Same as prep_for_like_query(), but called for "iexact" matches, which
- # need not necessarily be implemented using "LIKE" in the backend.
- prep_for_iexact_query = prep_for_like_query
-
- def validate_autopk_value(self, value):
- """
- Certain backends do not accept some values for "serial" fields
- (for example zero in MySQL). This method will raise a ValueError
- if the value is invalid, otherwise returns validated value.
- """
- return value
-
- def value_to_db_date(self, value):
- """
- Transform a date value to an object compatible with what is expected
- by the backend driver for date columns.
- """
- if value is None:
- return None
- return six.text_type(value)
-
- def value_to_db_datetime(self, value):
- """
- Transform a datetime value to an object compatible with what is expected
- by the backend driver for datetime columns.
- """
- if value is None:
- return None
- return six.text_type(value)
-
- def value_to_db_time(self, value):
- """
- Transform a time value to an object compatible with what is expected
- by the backend driver for time columns.
- """
- if value is None:
- return None
- if timezone.is_aware(value):
- raise ValueError("Django does not support timezone-aware times.")
- return six.text_type(value)
-
- def value_to_db_decimal(self, value, max_digits, decimal_places):
- """
- Transform a decimal.Decimal value to an object compatible with what is
- expected by the backend driver for decimal (numeric) columns.
- """
- if value is None:
- return None
- return util.format_number(value, max_digits, decimal_places)
-
- def year_lookup_bounds_for_date_field(self, value):
- """
- Returns a two-elements list with the lower and upper bound to be used
- with a BETWEEN operator to query a DateField value using a year
- lookup.
-
- `value` is an int, containing the looked-up year.
- """
- first = datetime.date(value, 1, 1)
- second = datetime.date(value, 12, 31)
- return [first, second]
-
- def year_lookup_bounds_for_datetime_field(self, value):
- """
- Returns a two-elements list with the lower and upper bound to be used
- with a BETWEEN operator to query a DateTimeField value using a year
- lookup.
-
- `value` is an int, containing the looked-up year.
- """
- first = datetime.datetime(value, 1, 1)
- second = datetime.datetime(value, 12, 31, 23, 59, 59, 999999)
- if settings.USE_TZ:
- tz = timezone.get_current_timezone()
- first = timezone.make_aware(first, tz)
- second = timezone.make_aware(second, tz)
- return [first, second]
-
- def convert_values(self, value, field):
- """
- Coerce the value returned by the database backend into a consistent type
- that is compatible with the field type.
- """
- if value is None or field is None:
- return value
- internal_type = field.get_internal_type()
- if internal_type == 'FloatField':
- return float(value)
- elif (internal_type and (internal_type.endswith('IntegerField')
- or internal_type == 'AutoField')):
- return int(value)
- return value
-
- def check_aggregate_support(self, aggregate_func):
- """Check that the backend supports the provided aggregate
-
- This is used on specific backends to rule out known aggregates
- that are known to have faulty implementations. If the named
- aggregate function has a known problem, the backend should
- raise NotImplementedError.
- """
- pass
-
- def combine_expression(self, connector, sub_expressions):
- """Combine a list of subexpressions into a single expression, using
- the provided connecting operator. This is required because operators
- can vary between backends (e.g., Oracle with %% and &) and between
- subexpression types (e.g., date expressions)
- """
- conn = ' %s ' % connector
- return conn.join(sub_expressions)
-
- def modify_insert_params(self, placeholders, params):
- """Allow modification of insert parameters. Needed for Oracle Spatial
- backend due to #10888.
- """
- return params
-
-
-# Structure returned by the DB-API cursor.description interface (PEP 249)
-FieldInfo = namedtuple('FieldInfo',
- 'name type_code display_size internal_size precision scale null_ok'
-)
-
-class BaseDatabaseIntrospection(object):
- """
- This class encapsulates all backend-specific introspection utilities
- """
- data_types_reverse = {}
-
- def __init__(self, connection):
- self.connection = connection
-
- def get_field_type(self, data_type, description):
- """Hook for a database backend to use the cursor description to
- match a Django field type to a database column.
-
- For Oracle, the column data_type on its own is insufficient to
- distinguish between a FloatField and IntegerField, for example."""
- return self.data_types_reverse[data_type]
-
- def table_name_converter(self, name):
- """Apply a conversion to the name for the purposes of comparison.
-
- The default table name converter is for case sensitive comparison.
- """
- return name
-
- def table_names(self, cursor=None):
- """
- Returns a list of names of all tables that exist in the database.
- The returned table list is sorted by Python's default sorting. We
- do NOT use database's ORDER BY here to avoid subtle differences
- in sorting order between databases.
- """
- if cursor is None:
- cursor = self.connection.cursor()
- return sorted(self.get_table_list(cursor))
-
- def get_table_list(self, cursor):
- """
- Returns an unsorted list of names of all tables that exist in the
- database.
- """
- raise NotImplementedError
-
- def django_table_names(self, only_existing=False):
- """
- Returns a list of all table names that have associated Django models and
- are in INSTALLED_APPS.
-
- If only_existing is True, the resulting list will only include the tables
- that actually exist in the database.
- """
- from django.db import models, router
- tables = set()
- for app in models.get_apps():
- for model in models.get_models(app):
- if not model._meta.managed:
- continue
- if not router.allow_syncdb(self.connection.alias, model):
- continue
- tables.add(model._meta.db_table)
- tables.update([f.m2m_db_table() for f in model._meta.local_many_to_many])
- tables = list(tables)
- if only_existing:
- existing_tables = self.table_names()
- tables = [
- t
- for t in tables
- if self.table_name_converter(t) in existing_tables
- ]
- return tables
-
- def installed_models(self, tables):
- "Returns a set of all models represented by the provided list of table names."
- from django.db import models, router
- all_models = []
- for app in models.get_apps():
- for model in models.get_models(app):
- if router.allow_syncdb(self.connection.alias, model):
- all_models.append(model)
- tables = list(map(self.table_name_converter, tables))
- return set([
- m for m in all_models
- if self.table_name_converter(m._meta.db_table) in tables
- ])
-
- def sequence_list(self):
- "Returns a list of information about all DB sequences for all models in all apps."
- from django.db import models, router
-
- apps = models.get_apps()
- sequence_list = []
-
- for app in apps:
- for model in models.get_models(app):
- if not model._meta.managed:
- continue
- if model._meta.swapped:
- continue
- if not router.allow_syncdb(self.connection.alias, model):
- continue
- for f in model._meta.local_fields:
- if isinstance(f, models.AutoField):
- sequence_list.append({'table': model._meta.db_table, 'column': f.column})
- break # Only one AutoField is allowed per model, so don't bother continuing.
-
- for f in model._meta.local_many_to_many:
- # If this is an m2m using an intermediate table,
- # we don't need to reset the sequence.
- if f.rel.through is None:
- sequence_list.append({'table': f.m2m_db_table(), 'column': None})
-
- return sequence_list
-
- def get_key_columns(self, cursor, table_name):
- """
- Backends can override this to return a list of (column_name, referenced_table_name,
- referenced_column_name) for all key columns in given table.
- """
- raise NotImplementedError
-
- def get_primary_key_column(self, cursor, table_name):
- """
- Returns the name of the primary key column for the given table.
- """
- for column in six.iteritems(self.get_indexes(cursor, table_name)):
- if column[1]['primary_key']:
- return column[0]
- return None
-
- def get_indexes(self, cursor, table_name):
- """
- Returns a dictionary of indexed fieldname -> infodict for the given
- table, where each infodict is in the format:
- {'primary_key': boolean representing whether it's the primary key,
- 'unique': boolean representing whether it's a unique index}
-
- Only single-column indexes are introspected.
- """
- raise NotImplementedError
-
-
-class BaseDatabaseClient(object):
- """
- This class encapsulates all backend-specific methods for opening a
- client shell.
- """
- # This should be a string representing the name of the executable
- # (e.g., "psql"). Subclasses must override this.
- executable_name = None
-
- def __init__(self, connection):
- # connection is an instance of BaseDatabaseWrapper.
- self.connection = connection
-
- def runshell(self):
- raise NotImplementedError()
-
-
-class BaseDatabaseValidation(object):
- """
- This class encapsualtes all backend-specific model validation.
- """
- def __init__(self, connection):
- self.connection = connection
-
- def validate_field(self, errors, opts, f):
- "By default, there is no backend-specific validation"
- pass
diff --git a/lib/python2.7/site-packages/django/db/backends/creation.py b/lib/python2.7/site-packages/django/db/backends/creation.py
deleted file mode 100644
index bae439b..0000000
--- a/lib/python2.7/site-packages/django/db/backends/creation.py
+++ /dev/null
@@ -1,489 +0,0 @@
-import hashlib
-import sys
-import time
-import warnings
-
-from django.conf import settings
-from django.db.utils import load_backend
-from django.utils.encoding import force_bytes
-from django.utils.six.moves import input
-
-from .util import truncate_name
-
-# The prefix to put on the default database name when creating
-# the test database.
-TEST_DATABASE_PREFIX = 'test_'
-
-
-class BaseDatabaseCreation(object):
- """
- This class encapsulates all backend-specific differences that pertain to
- database *creation*, such as the column types to use for particular Django
- Fields, the SQL used to create and destroy tables, and the creation and
- destruction of test databases.
- """
- data_types = {}
-
- def __init__(self, connection):
- self.connection = connection
-
- def _digest(self, *args):
- """
- Generates a 32-bit digest of a set of arguments that can be used to
- shorten identifying names.
- """
- h = hashlib.md5()
- for arg in args:
- h.update(force_bytes(arg))
- return h.hexdigest()[:8]
-
- def sql_create_model(self, model, style, known_models=set()):
- """
- Returns the SQL required to create a single model, as a tuple of:
- (list_of_sql, pending_references_dict)
- """
- opts = model._meta
- if not opts.managed or opts.proxy or opts.swapped:
- return [], {}
- final_output = []
- table_output = []
- pending_references = {}
- qn = self.connection.ops.quote_name
- for f in opts.local_fields:
- col_type = f.db_type(connection=self.connection)
- tablespace = f.db_tablespace or opts.db_tablespace
- if col_type is None:
- # Skip ManyToManyFields, because they're not represented as
- # database columns in this table.
- continue
- # Make the definition (e.g. 'foo VARCHAR(30)') for this field.
- field_output = [style.SQL_FIELD(qn(f.column)),
- style.SQL_COLTYPE(col_type)]
- # Oracle treats the empty string ('') as null, so coerce the null
- # option whenever '' is a possible value.
- null = f.null
- if (f.empty_strings_allowed and not f.primary_key and
- self.connection.features.interprets_empty_strings_as_nulls):
- null = True
- if not null:
- field_output.append(style.SQL_KEYWORD('NOT NULL'))
- if f.primary_key:
- field_output.append(style.SQL_KEYWORD('PRIMARY KEY'))
- elif f.unique:
- field_output.append(style.SQL_KEYWORD('UNIQUE'))
- if tablespace and f.unique:
- # We must specify the index tablespace inline, because we
- # won't be generating a CREATE INDEX statement for this field.
- tablespace_sql = self.connection.ops.tablespace_sql(
- tablespace, inline=True)
- if tablespace_sql:
- field_output.append(tablespace_sql)
- if f.rel and f.db_constraint:
- ref_output, pending = self.sql_for_inline_foreign_key_references(
- model, f, known_models, style)
- if pending:
- pending_references.setdefault(f.rel.to, []).append(
- (model, f))
- else:
- field_output.extend(ref_output)
- table_output.append(' '.join(field_output))
- for field_constraints in opts.unique_together:
- table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' %
- ", ".join(
- [style.SQL_FIELD(qn(opts.get_field(f).column))
- for f in field_constraints]))
-
- full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' +
- style.SQL_TABLE(qn(opts.db_table)) + ' (']
- for i, line in enumerate(table_output): # Combine and add commas.
- full_statement.append(
- ' %s%s' % (line, ',' if i < len(table_output) - 1 else ''))
- full_statement.append(')')
- if opts.db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(
- opts.db_tablespace)
- if tablespace_sql:
- full_statement.append(tablespace_sql)
- full_statement.append(';')
- final_output.append('\n'.join(full_statement))
-
- if opts.has_auto_field:
- # Add any extra SQL needed to support auto-incrementing primary
- # keys.
- auto_column = opts.auto_field.db_column or opts.auto_field.name
- autoinc_sql = self.connection.ops.autoinc_sql(opts.db_table,
- auto_column)
- if autoinc_sql:
- for stmt in autoinc_sql:
- final_output.append(stmt)
-
- return final_output, pending_references
-
- def sql_for_inline_foreign_key_references(self, model, field, known_models, style):
- """
- Return the SQL snippet defining the foreign key reference for a field.
- """
- qn = self.connection.ops.quote_name
- rel_to = field.rel.to
- if rel_to in known_models or rel_to == model:
- output = [style.SQL_KEYWORD('REFERENCES') + ' ' +
- style.SQL_TABLE(qn(rel_to._meta.db_table)) + ' (' +
- style.SQL_FIELD(qn(rel_to._meta.get_field(
- field.rel.field_name).column)) + ')' +
- self.connection.ops.deferrable_sql()
- ]
- pending = False
- else:
- # We haven't yet created the table to which this field
- # is related, so save it for later.
- output = []
- pending = True
-
- return output, pending
-
- def sql_for_pending_references(self, model, style, pending_references):
- """
- Returns any ALTER TABLE statements to add constraints after the fact.
- """
- opts = model._meta
- if not opts.managed or opts.swapped:
- return []
- qn = self.connection.ops.quote_name
- final_output = []
- if model in pending_references:
- for rel_class, f in pending_references[model]:
- rel_opts = rel_class._meta
- r_table = rel_opts.db_table
- r_col = f.column
- table = opts.db_table
- col = opts.get_field(f.rel.field_name).column
- # For MySQL, r_name must be unique in the first 64 characters.
- # So we are careful with character usage here.
- r_name = '%s_refs_%s_%s' % (
- r_col, col, self._digest(r_table, table))
- final_output.append(style.SQL_KEYWORD('ALTER TABLE') +
- ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' %
- (qn(r_table), qn(truncate_name(
- r_name, self.connection.ops.max_name_length())),
- qn(r_col), qn(table), qn(col),
- self.connection.ops.deferrable_sql()))
- del pending_references[model]
- return final_output
-
- def sql_indexes_for_model(self, model, style):
- """
- Returns the CREATE INDEX SQL statements for a single model.
- """
- if not model._meta.managed or model._meta.proxy or model._meta.swapped:
- return []
- output = []
- for f in model._meta.local_fields:
- output.extend(self.sql_indexes_for_field(model, f, style))
- for fs in model._meta.index_together:
- fields = [model._meta.get_field_by_name(f)[0] for f in fs]
- output.extend(self.sql_indexes_for_fields(model, fields, style))
- return output
-
- def sql_indexes_for_field(self, model, f, style):
- """
- Return the CREATE INDEX SQL statements for a single model field.
- """
- if f.db_index and not f.unique:
- return self.sql_indexes_for_fields(model, [f], style)
- else:
- return []
-
- def sql_indexes_for_fields(self, model, fields, style):
- if len(fields) == 1 and fields[0].db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(fields[0].db_tablespace)
- elif model._meta.db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
- else:
- tablespace_sql = ""
- if tablespace_sql:
- tablespace_sql = " " + tablespace_sql
-
- field_names = []
- qn = self.connection.ops.quote_name
- for f in fields:
- field_names.append(style.SQL_FIELD(qn(f.column)))
-
- index_name = "%s_%s" % (model._meta.db_table, self._digest([f.name for f in fields]))
-
- return [
- style.SQL_KEYWORD("CREATE INDEX") + " " +
- style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + " " +
- style.SQL_KEYWORD("ON") + " " +
- style.SQL_TABLE(qn(model._meta.db_table)) + " " +
- "(%s)" % style.SQL_FIELD(", ".join(field_names)) +
- "%s;" % tablespace_sql,
- ]
-
- def sql_destroy_model(self, model, references_to_delete, style):
- """
- Return the DROP TABLE and restraint dropping statements for a single
- model.
- """
- if not model._meta.managed or model._meta.proxy or model._meta.swapped:
- return []
- # Drop the table now
- qn = self.connection.ops.quote_name
- output = ['%s %s;' % (style.SQL_KEYWORD('DROP TABLE'),
- style.SQL_TABLE(qn(model._meta.db_table)))]
- if model in references_to_delete:
- output.extend(self.sql_remove_table_constraints(
- model, references_to_delete, style))
- if model._meta.has_auto_field:
- ds = self.connection.ops.drop_sequence_sql(model._meta.db_table)
- if ds:
- output.append(ds)
- return output
-
- def sql_remove_table_constraints(self, model, references_to_delete, style):
- if not model._meta.managed or model._meta.proxy or model._meta.swapped:
- return []
- output = []
- qn = self.connection.ops.quote_name
- for rel_class, f in references_to_delete[model]:
- table = rel_class._meta.db_table
- col = f.column
- r_table = model._meta.db_table
- r_col = model._meta.get_field(f.rel.field_name).column
- r_name = '%s_refs_%s_%s' % (
- col, r_col, self._digest(table, r_table))
- output.append('%s %s %s %s;' % \
- (style.SQL_KEYWORD('ALTER TABLE'),
- style.SQL_TABLE(qn(table)),
- style.SQL_KEYWORD(self.connection.ops.drop_foreignkey_sql()),
- style.SQL_FIELD(qn(truncate_name(
- r_name, self.connection.ops.max_name_length())))))
- del references_to_delete[model]
- return output
-
- def sql_destroy_indexes_for_model(self, model, style):
- """
- Returns the DROP INDEX SQL statements for a single model.
- """
- if not model._meta.managed or model._meta.proxy or model._meta.swapped:
- return []
- output = []
- for f in model._meta.local_fields:
- output.extend(self.sql_destroy_indexes_for_field(model, f, style))
- for fs in model._meta.index_together:
- fields = [model._meta.get_field_by_name(f)[0] for f in fs]
- output.extend(self.sql_destroy_indexes_for_fields(model, fields, style))
- return output
-
- def sql_destroy_indexes_for_field(self, model, f, style):
- """
- Return the DROP INDEX SQL statements for a single model field.
- """
- if f.db_index and not f.unique:
- return self.sql_destroy_indexes_for_fields(model, [f], style)
- else:
- return []
-
- def sql_destroy_indexes_for_fields(self, model, fields, style):
- if len(fields) == 1 and fields[0].db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(fields[0].db_tablespace)
- elif model._meta.db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
- else:
- tablespace_sql = ""
- if tablespace_sql:
- tablespace_sql = " " + tablespace_sql
-
- field_names = []
- qn = self.connection.ops.quote_name
- for f in fields:
- field_names.append(style.SQL_FIELD(qn(f.column)))
-
- index_name = "%s_%s" % (model._meta.db_table, self._digest([f.name for f in fields]))
-
- return [
- style.SQL_KEYWORD("DROP INDEX") + " " +
- style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + " " +
- ";",
- ]
-
- def create_test_db(self, verbosity=1, autoclobber=False):
- """
- Creates a test database, prompting the user for confirmation if the
- database already exists. Returns the name of the test database created.
- """
- # Don't import django.core.management if it isn't needed.
- from django.core.management import call_command
-
- test_database_name = self._get_test_db_name()
-
- if verbosity >= 1:
- test_db_repr = ''
- if verbosity >= 2:
- test_db_repr = " ('%s')" % test_database_name
- print("Creating test database for alias '%s'%s..." % (
- self.connection.alias, test_db_repr))
-
- self._create_test_db(verbosity, autoclobber)
-
- self.connection.close()
- settings.DATABASES[self.connection.alias]["NAME"] = test_database_name
- self.connection.settings_dict["NAME"] = test_database_name
-
- # Report syncdb messages at one level lower than that requested.
- # This ensures we don't get flooded with messages during testing
- # (unless you really ask to be flooded)
- call_command('syncdb',
- verbosity=max(verbosity - 1, 0),
- interactive=False,
- database=self.connection.alias,
- load_initial_data=False)
-
- # We need to then do a flush to ensure that any data installed by
- # custom SQL has been removed. The only test data should come from
- # test fixtures, or autogenerated from post_syncdb triggers.
- # This has the side effect of loading initial data (which was
- # intentionally skipped in the syncdb).
- call_command('flush',
- verbosity=max(verbosity - 1, 0),
- interactive=False,
- database=self.connection.alias)
-
- from django.core.cache import get_cache
- from django.core.cache.backends.db import BaseDatabaseCache
- for cache_alias in settings.CACHES:
- cache = get_cache(cache_alias)
- if isinstance(cache, BaseDatabaseCache):
- call_command('createcachetable', cache._table,
- database=self.connection.alias)
-
- # Get a cursor (even though we don't need one yet). This has
- # the side effect of initializing the test database.
- self.connection.cursor()
-
- return test_database_name
-
- def _get_test_db_name(self):
- """
- Internal implementation - returns the name of the test DB that will be
- created. Only useful when called from create_test_db() and
- _create_test_db() and when no external munging is done with the 'NAME'
- or 'TEST_NAME' settings.
- """
- if self.connection.settings_dict['TEST_NAME']:
- return self.connection.settings_dict['TEST_NAME']
- return TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
-
- def _create_test_db(self, verbosity, autoclobber):
- """
- Internal implementation - creates the test db tables.
- """
- suffix = self.sql_table_creation_suffix()
-
- test_database_name = self._get_test_db_name()
-
- qn = self.connection.ops.quote_name
-
- # Create the test database and connect to it.
- cursor = self.connection.cursor()
- try:
- cursor.execute(
- "CREATE DATABASE %s %s" % (qn(test_database_name), suffix))
- except Exception as e:
- sys.stderr.write(
- "Got an error creating the test database: %s\n" % e)
- if not autoclobber:
- confirm = input(
- "Type 'yes' if you would like to try deleting the test "
- "database '%s', or 'no' to cancel: " % test_database_name)
- if autoclobber or confirm == 'yes':
- try:
- if verbosity >= 1:
- print("Destroying old test database '%s'..."
- % self.connection.alias)
- cursor.execute(
- "DROP DATABASE %s" % qn(test_database_name))
- cursor.execute(
- "CREATE DATABASE %s %s" % (qn(test_database_name),
- suffix))
- except Exception as e:
- sys.stderr.write(
- "Got an error recreating the test database: %s\n" % e)
- sys.exit(2)
- else:
- print("Tests cancelled.")
- sys.exit(1)
-
- return test_database_name
-
- def destroy_test_db(self, old_database_name, verbosity=1):
- """
- Destroy a test database, prompting the user for confirmation if the
- database already exists.
- """
- self.connection.close()
- test_database_name = self.connection.settings_dict['NAME']
- if verbosity >= 1:
- test_db_repr = ''
- if verbosity >= 2:
- test_db_repr = " ('%s')" % test_database_name
- print("Destroying test database for alias '%s'%s..." % (
- self.connection.alias, test_db_repr))
-
- # Temporarily use a new connection and a copy of the settings dict.
- # This prevents the production database from being exposed to potential
- # child threads while (or after) the test database is destroyed.
- # Refs #10868 and #17786.
- settings_dict = self.connection.settings_dict.copy()
- settings_dict['NAME'] = old_database_name
- backend = load_backend(settings_dict['ENGINE'])
- new_connection = backend.DatabaseWrapper(
- settings_dict,
- alias='__destroy_test_db__',
- allow_thread_sharing=False)
- new_connection.creation._destroy_test_db(test_database_name, verbosity)
-
- def _destroy_test_db(self, test_database_name, verbosity):
- """
- Internal implementation - remove the test db tables.
- """
- # Remove the test database to clean up after
- # ourselves. Connect to the previous database (not the test database)
- # to do so, because it's not allowed to delete a database while being
- # connected to it.
- cursor = self.connection.cursor()
- # Wait to avoid "database is being accessed by other users" errors.
- time.sleep(1)
- cursor.execute("DROP DATABASE %s"
- % self.connection.ops.quote_name(test_database_name))
- self.connection.close()
-
- def set_autocommit(self):
- """
- Make sure a connection is in autocommit mode. - Deprecated, not used
- anymore by Django code. Kept for compatibility with user code that
- might use it.
- """
- warnings.warn(
- "set_autocommit was moved from BaseDatabaseCreation to "
- "BaseDatabaseWrapper.", PendingDeprecationWarning, stacklevel=2)
- return self.connection.set_autocommit(True)
-
- def sql_table_creation_suffix(self):
- """
- SQL to append to the end of the test table creation statements.
- """
- return ''
-
- def test_db_signature(self):
- """
- Returns a tuple with elements of self.connection.settings_dict (a
- DATABASES setting value) that uniquely identify a database
- accordingly to the RDBMS particularities.
- """
- settings_dict = self.connection.settings_dict
- return (
- settings_dict['HOST'],
- settings_dict['PORT'],
- settings_dict['ENGINE'],
- settings_dict['NAME']
- )
diff --git a/lib/python2.7/site-packages/django/db/backends/dummy/__init__.py b/lib/python2.7/site-packages/django/db/backends/dummy/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/lib/python2.7/site-packages/django/db/backends/dummy/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/django/db/backends/dummy/base.py b/lib/python2.7/site-packages/django/db/backends/dummy/base.py
deleted file mode 100644
index 9a220ff..0000000
--- a/lib/python2.7/site-packages/django/db/backends/dummy/base.py
+++ /dev/null
@@ -1,73 +0,0 @@
-"""
-Dummy database backend for Django.
-
-Django uses this if the database ENGINE setting is empty (None or empty string).
-
-Each of these API functions, except connection.close(), raises
-ImproperlyConfigured.
-"""
-
-from django.core.exceptions import ImproperlyConfigured
-from django.db.backends import *
-from django.db.backends.creation import BaseDatabaseCreation
-
-def complain(*args, **kwargs):
- raise ImproperlyConfigured("settings.DATABASES is improperly configured. "
- "Please supply the ENGINE value. Check "
- "settings documentation for more details.")
-
-def ignore(*args, **kwargs):
- pass
-
-class DatabaseError(Exception):
- pass
-
-class IntegrityError(DatabaseError):
- pass
-
-class DatabaseOperations(BaseDatabaseOperations):
- quote_name = complain
-
-class DatabaseClient(BaseDatabaseClient):
- runshell = complain
-
-class DatabaseCreation(BaseDatabaseCreation):
- create_test_db = ignore
- destroy_test_db = ignore
-
-class DatabaseIntrospection(BaseDatabaseIntrospection):
- get_table_list = complain
- get_table_description = complain
- get_relations = complain
- get_indexes = complain
- get_key_columns = complain
-
-class DatabaseWrapper(BaseDatabaseWrapper):
- operators = {}
- # Override the base class implementations with null
- # implementations. Anything that tries to actually
- # do something raises complain; anything that tries
- # to rollback or undo something raises ignore.
- _cursor = complain
- _commit = complain
- _rollback = ignore
- _close = ignore
- _savepoint = ignore
- _savepoint_commit = complain
- _savepoint_rollback = ignore
- _set_autocommit = complain
- set_dirty = complain
- set_clean = complain
-
- def __init__(self, *args, **kwargs):
- super(DatabaseWrapper, self).__init__(*args, **kwargs)
-
- self.features = BaseDatabaseFeatures(self)
- self.ops = DatabaseOperations(self)
- self.client = DatabaseClient(self)
- self.creation = DatabaseCreation(self)
- self.introspection = DatabaseIntrospection(self)
- self.validation = BaseDatabaseValidation(self)
-
- def is_usable(self):
- return True
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/__init__.py b/lib/python2.7/site-packages/django/db/backends/mysql/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/base.py b/lib/python2.7/site-packages/django/db/backends/mysql/base.py
deleted file mode 100644
index ea04a5e..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/base.py
+++ /dev/null
@@ -1,533 +0,0 @@
-"""
-MySQL database backend for Django.
-
-Requires MySQLdb: http://sourceforge.net/projects/mysql-python
-"""
-from __future__ import unicode_literals
-
-import datetime
-import re
-import sys
-import warnings
-
-try:
- import MySQLdb as Database
-except ImportError as e:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
-
-from django.utils.functional import cached_property
-
-# We want version (1, 2, 1, 'final', 2) or later. We can't just use
-# lexicographic ordering in this check because then (1, 2, 1, 'gamma')
-# inadvertently passes the version test.
-version = Database.version_info
-if (version < (1, 2, 1) or (version[:3] == (1, 2, 1) and
- (len(version) < 5 or version[3] != 'final' or version[4] < 2))):
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
-
-from MySQLdb.converters import conversions, Thing2Literal
-from MySQLdb.constants import FIELD_TYPE, CLIENT
-
-try:
- import pytz
-except ImportError:
- pytz = None
-
-from django.conf import settings
-from django.db import utils
-from django.db.backends import *
-from django.db.backends.mysql.client import DatabaseClient
-from django.db.backends.mysql.creation import DatabaseCreation
-from django.db.backends.mysql.introspection import DatabaseIntrospection
-from django.db.backends.mysql.validation import DatabaseValidation
-from django.utils.encoding import force_str, force_text
-from django.utils.safestring import SafeBytes, SafeText
-from django.utils import six
-from django.utils import timezone
-
-# Raise exceptions for database warnings if DEBUG is on
-if settings.DEBUG:
- warnings.filterwarnings("error", category=Database.Warning)
-
-DatabaseError = Database.DatabaseError
-IntegrityError = Database.IntegrityError
-
-# It's impossible to import datetime_or_None directly from MySQLdb.times
-parse_datetime = conversions[FIELD_TYPE.DATETIME]
-
-def parse_datetime_with_timezone_support(value):
- dt = parse_datetime(value)
- # Confirm that dt is naive before overwriting its tzinfo.
- if dt is not None and settings.USE_TZ and timezone.is_naive(dt):
- dt = dt.replace(tzinfo=timezone.utc)
- return dt
-
-def adapt_datetime_with_timezone_support(value, conv):
- # Equivalent to DateTimeField.get_db_prep_value. Used only by raw SQL.
- if settings.USE_TZ:
- if timezone.is_naive(value):
- warnings.warn("MySQL received a naive datetime (%s)"
- " while time zone support is active." % value,
- RuntimeWarning)
- default_timezone = timezone.get_default_timezone()
- value = timezone.make_aware(value, default_timezone)
- value = value.astimezone(timezone.utc).replace(tzinfo=None)
- return Thing2Literal(value.strftime("%Y-%m-%d %H:%M:%S"), conv)
-
-# MySQLdb-1.2.1 returns TIME columns as timedelta -- they are more like
-# timedelta in terms of actual behavior as they are signed and include days --
-# and Django expects time, so we still need to override that. We also need to
-# add special handling for SafeText and SafeBytes as MySQLdb's type
-# checking is too tight to catch those (see Django ticket #6052).
-# Finally, MySQLdb always returns naive datetime objects. However, when
-# timezone support is active, Django expects timezone-aware datetime objects.
-django_conversions = conversions.copy()
-django_conversions.update({
- FIELD_TYPE.TIME: util.typecast_time,
- FIELD_TYPE.DECIMAL: util.typecast_decimal,
- FIELD_TYPE.NEWDECIMAL: util.typecast_decimal,
- FIELD_TYPE.DATETIME: parse_datetime_with_timezone_support,
- datetime.datetime: adapt_datetime_with_timezone_support,
-})
-
-# This should match the numerical portion of the version numbers (we can treat
-# versions like 5.0.24 and 5.0.24a as the same). Based on the list of version
-# at http://dev.mysql.com/doc/refman/4.1/en/news.html and
-# http://dev.mysql.com/doc/refman/5.0/en/news.html .
-server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})')
-
-# MySQLdb-1.2.1 and newer automatically makes use of SHOW WARNINGS on
-# MySQL-4.1 and newer, so the MysqlDebugWrapper is unnecessary. Since the
-# point is to raise Warnings as exceptions, this can be done with the Python
-# warning module, and this is setup when the connection is created, and the
-# standard util.CursorDebugWrapper can be used. Also, using sql_mode
-# TRADITIONAL will automatically cause most warnings to be treated as errors.
-
-class CursorWrapper(object):
- """
- A thin wrapper around MySQLdb's normal cursor class so that we can catch
- particular exception instances and reraise them with the right types.
-
- Implemented as a wrapper, rather than a subclass, so that we aren't stuck
- to the particular underlying representation returned by Connection.cursor().
- """
- codes_for_integrityerror = (1048,)
-
- def __init__(self, cursor):
- self.cursor = cursor
-
- def execute(self, query, args=None):
- try:
- # args is None means no string interpolation
- return self.cursor.execute(query, args)
- except Database.OperationalError as e:
- # Map some error codes to IntegrityError, since they seem to be
- # misclassified and Django would prefer the more logical place.
- if e.args[0] in self.codes_for_integrityerror:
- six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
- raise
-
- def executemany(self, query, args):
- try:
- return self.cursor.executemany(query, args)
- except Database.OperationalError as e:
- # Map some error codes to IntegrityError, since they seem to be
- # misclassified and Django would prefer the more logical place.
- if e.args[0] in self.codes_for_integrityerror:
- six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
- raise
-
- def __getattr__(self, attr):
- if attr in self.__dict__:
- return self.__dict__[attr]
- else:
- return getattr(self.cursor, attr)
-
- def __iter__(self):
- return iter(self.cursor)
-
-class DatabaseFeatures(BaseDatabaseFeatures):
- empty_fetchmany_value = ()
- update_can_self_select = False
- allows_group_by_pk = True
- related_fields_match_type = True
- allow_sliced_subqueries = False
- has_bulk_insert = True
- has_select_for_update = True
- has_select_for_update_nowait = False
- supports_forward_references = False
- supports_long_model_names = False
- supports_microsecond_precision = False
- supports_regex_backreferencing = False
- supports_date_lookup_using_string = False
- supports_timezones = False
- requires_explicit_null_ordering_when_grouping = True
- allows_primary_key_0 = False
- uses_savepoints = True
- atomic_transactions = False
-
- def __init__(self, connection):
- super(DatabaseFeatures, self).__init__(connection)
-
- @cached_property
- def _mysql_storage_engine(self):
- "Internal method used in Django tests. Don't rely on this from your code"
- cursor = self.connection.cursor()
- cursor.execute('CREATE TABLE INTROSPECT_TEST (X INT)')
- # This command is MySQL specific; the second column
- # will tell you the default table type of the created
- # table. Since all Django's test tables will have the same
- # table type, that's enough to evaluate the feature.
- cursor.execute("SHOW TABLE STATUS WHERE Name='INTROSPECT_TEST'")
- result = cursor.fetchone()
- cursor.execute('DROP TABLE INTROSPECT_TEST')
- return result[1]
-
- @cached_property
- def can_introspect_foreign_keys(self):
- "Confirm support for introspected foreign keys"
- return self._mysql_storage_engine != 'MyISAM'
-
- @cached_property
- def has_zoneinfo_database(self):
- # MySQL accepts full time zones names (eg. Africa/Nairobi) but rejects
- # abbreviations (eg. EAT). When pytz isn't installed and the current
- # time zone is LocalTimezone (the only sensible value in this
- # context), the current time zone name will be an abbreviation. As a
- # consequence, MySQL cannot perform time zone conversions reliably.
- if pytz is None:
- return False
-
- # Test if the time zone definitions are installed.
- cursor = self.connection.cursor()
- cursor.execute("SELECT 1 FROM mysql.time_zone LIMIT 1")
- return cursor.fetchone() is not None
-
-class DatabaseOperations(BaseDatabaseOperations):
- compiler_module = "django.db.backends.mysql.compiler"
-
- def date_extract_sql(self, lookup_type, field_name):
- # http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
- if lookup_type == 'week_day':
- # DAYOFWEEK() returns an integer, 1-7, Sunday=1.
- # Note: WEEKDAY() returns 0-6, Monday=0.
- return "DAYOFWEEK(%s)" % field_name
- else:
- return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
-
- def date_trunc_sql(self, lookup_type, field_name):
- fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
- format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
- format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
- try:
- i = fields.index(lookup_type) + 1
- except ValueError:
- sql = field_name
- else:
- format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
- sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
- return sql
-
- def datetime_extract_sql(self, lookup_type, field_name, tzname):
- if settings.USE_TZ:
- field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
- params = [tzname]
- else:
- params = []
- # http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
- if lookup_type == 'week_day':
- # DAYOFWEEK() returns an integer, 1-7, Sunday=1.
- # Note: WEEKDAY() returns 0-6, Monday=0.
- sql = "DAYOFWEEK(%s)" % field_name
- else:
- sql = "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
- return sql, params
-
- def datetime_trunc_sql(self, lookup_type, field_name, tzname):
- if settings.USE_TZ:
- field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
- params = [tzname]
- else:
- params = []
- fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
- format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
- format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
- try:
- i = fields.index(lookup_type) + 1
- except ValueError:
- sql = field_name
- else:
- format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
- sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
- return sql, params
-
- def date_interval_sql(self, sql, connector, timedelta):
- return "(%s %s INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND)" % (sql, connector,
- timedelta.days, timedelta.seconds, timedelta.microseconds)
-
- def drop_foreignkey_sql(self):
- return "DROP FOREIGN KEY"
-
- def force_no_ordering(self):
- """
- "ORDER BY NULL" prevents MySQL from implicitly ordering by grouped
- columns. If no ordering would otherwise be applied, we don't want any
- implicit sorting going on.
- """
- return ["NULL"]
-
- def fulltext_search_sql(self, field_name):
- return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name
-
- def last_executed_query(self, cursor, sql, params):
- # With MySQLdb, cursor objects have an (undocumented) "_last_executed"
- # attribute where the exact query sent to the database is saved.
- # See MySQLdb/cursors.py in the source distribution.
- return force_text(getattr(cursor, '_last_executed', None), errors='replace')
-
- def no_limit_value(self):
- # 2**64 - 1, as recommended by the MySQL documentation
- return 18446744073709551615
-
- def quote_name(self, name):
- if name.startswith("`") and name.endswith("`"):
- return name # Quoting once is enough.
- return "`%s`" % name
-
- def random_function_sql(self):
- return 'RAND()'
-
- def sql_flush(self, style, tables, sequences, allow_cascade=False):
- # NB: The generated SQL below is specific to MySQL
- # 'TRUNCATE x;', 'TRUNCATE y;', 'TRUNCATE z;'... style SQL statements
- # to clear all tables of all data
- if tables:
- sql = ['SET FOREIGN_KEY_CHECKS = 0;']
- for table in tables:
- sql.append('%s %s;' % (
- style.SQL_KEYWORD('TRUNCATE'),
- style.SQL_FIELD(self.quote_name(table)),
- ))
- sql.append('SET FOREIGN_KEY_CHECKS = 1;')
- sql.extend(self.sequence_reset_by_name_sql(style, sequences))
- return sql
- else:
- return []
-
- def sequence_reset_by_name_sql(self, style, sequences):
- # Truncate already resets the AUTO_INCREMENT field from
- # MySQL version 5.0.13 onwards. Refs #16961.
- if self.connection.mysql_version < (5, 0, 13):
- return ["%s %s %s %s %s;" % \
- (style.SQL_KEYWORD('ALTER'),
- style.SQL_KEYWORD('TABLE'),
- style.SQL_TABLE(self.quote_name(sequence['table'])),
- style.SQL_KEYWORD('AUTO_INCREMENT'),
- style.SQL_FIELD('= 1'),
- ) for sequence in sequences]
- else:
- return []
-
- def validate_autopk_value(self, value):
- # MySQLism: zero in AUTO_INCREMENT field does not work. Refs #17653.
- if value == 0:
- raise ValueError('The database backend does not accept 0 as a '
- 'value for AutoField.')
- return value
-
- def value_to_db_datetime(self, value):
- if value is None:
- return None
-
- # MySQL doesn't support tz-aware datetimes
- if timezone.is_aware(value):
- if settings.USE_TZ:
- value = value.astimezone(timezone.utc).replace(tzinfo=None)
- else:
- raise ValueError("MySQL backend does not support timezone-aware datetimes when USE_TZ is False.")
-
- # MySQL doesn't support microseconds
- return six.text_type(value.replace(microsecond=0))
-
- def value_to_db_time(self, value):
- if value is None:
- return None
-
- # MySQL doesn't support tz-aware times
- if timezone.is_aware(value):
- raise ValueError("MySQL backend does not support timezone-aware times.")
-
- # MySQL doesn't support microseconds
- return six.text_type(value.replace(microsecond=0))
-
- def year_lookup_bounds_for_datetime_field(self, value):
- # Again, no microseconds
- first, second = super(DatabaseOperations, self).year_lookup_bounds_for_datetime_field(value)
- return [first.replace(microsecond=0), second.replace(microsecond=0)]
-
- def max_name_length(self):
- return 64
-
- def bulk_insert_sql(self, fields, num_values):
- items_sql = "(%s)" % ", ".join(["%s"] * len(fields))
- return "VALUES " + ", ".join([items_sql] * num_values)
-
-class DatabaseWrapper(BaseDatabaseWrapper):
- vendor = 'mysql'
- operators = {
- 'exact': '= %s',
- 'iexact': 'LIKE %s',
- 'contains': 'LIKE BINARY %s',
- 'icontains': 'LIKE %s',
- 'regex': 'REGEXP BINARY %s',
- 'iregex': 'REGEXP %s',
- 'gt': '> %s',
- 'gte': '>= %s',
- 'lt': '< %s',
- 'lte': '<= %s',
- 'startswith': 'LIKE BINARY %s',
- 'endswith': 'LIKE BINARY %s',
- 'istartswith': 'LIKE %s',
- 'iendswith': 'LIKE %s',
- }
-
- Database = Database
-
- def __init__(self, *args, **kwargs):
- super(DatabaseWrapper, self).__init__(*args, **kwargs)
-
- self.features = DatabaseFeatures(self)
- self.ops = DatabaseOperations(self)
- self.client = DatabaseClient(self)
- self.creation = DatabaseCreation(self)
- self.introspection = DatabaseIntrospection(self)
- self.validation = DatabaseValidation(self)
-
- def get_connection_params(self):
- kwargs = {
- 'conv': django_conversions,
- 'charset': 'utf8',
- }
- if six.PY2:
- kwargs['use_unicode'] = True
- settings_dict = self.settings_dict
- if settings_dict['USER']:
- kwargs['user'] = settings_dict['USER']
- if settings_dict['NAME']:
- kwargs['db'] = settings_dict['NAME']
- if settings_dict['PASSWORD']:
- kwargs['passwd'] = force_str(settings_dict['PASSWORD'])
- if settings_dict['HOST'].startswith('/'):
- kwargs['unix_socket'] = settings_dict['HOST']
- elif settings_dict['HOST']:
- kwargs['host'] = settings_dict['HOST']
- if settings_dict['PORT']:
- kwargs['port'] = int(settings_dict['PORT'])
- # We need the number of potentially affected rows after an
- # "UPDATE", not the number of changed rows.
- kwargs['client_flag'] = CLIENT.FOUND_ROWS
- kwargs.update(settings_dict['OPTIONS'])
- return kwargs
-
- def get_new_connection(self, conn_params):
- conn = Database.connect(**conn_params)
- conn.encoders[SafeText] = conn.encoders[six.text_type]
- conn.encoders[SafeBytes] = conn.encoders[bytes]
- return conn
-
- def init_connection_state(self):
- cursor = self.connection.cursor()
- # SQL_AUTO_IS_NULL in MySQL controls whether an AUTO_INCREMENT column
- # on a recently-inserted row will return when the field is tested for
- # NULL. Disabling this value brings this aspect of MySQL in line with
- # SQL standards.
- cursor.execute('SET SQL_AUTO_IS_NULL = 0')
- cursor.close()
-
- def create_cursor(self):
- cursor = self.connection.cursor()
- return CursorWrapper(cursor)
-
- def _rollback(self):
- try:
- BaseDatabaseWrapper._rollback(self)
- except Database.NotSupportedError:
- pass
-
- def _set_autocommit(self, autocommit):
- with self.wrap_database_errors:
- self.connection.autocommit(autocommit)
-
- def disable_constraint_checking(self):
- """
- Disables foreign key checks, primarily for use in adding rows with forward references. Always returns True,
- to indicate constraint checks need to be re-enabled.
- """
- self.cursor().execute('SET foreign_key_checks=0')
- return True
-
- def enable_constraint_checking(self):
- """
- Re-enable foreign key checks after they have been disabled.
- """
- # Override needs_rollback in case constraint_checks_disabled is
- # nested inside transaction.atomic.
- self.needs_rollback, needs_rollback = False, self.needs_rollback
- try:
- self.cursor().execute('SET foreign_key_checks=1')
- finally:
- self.needs_rollback = needs_rollback
-
- def check_constraints(self, table_names=None):
- """
- Checks each table name in `table_names` for rows with invalid foreign key references. This method is
- intended to be used in conjunction with `disable_constraint_checking()` and `enable_constraint_checking()`, to
- determine if rows with invalid references were entered while constraint checks were off.
-
- Raises an IntegrityError on the first invalid foreign key reference encountered (if any) and provides
- detailed information about the invalid reference in the error message.
-
- Backends can override this method if they can more directly apply constraint checking (e.g. via "SET CONSTRAINTS
- ALL IMMEDIATE")
- """
- cursor = self.cursor()
- if table_names is None:
- table_names = self.introspection.table_names(cursor)
- for table_name in table_names:
- primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name)
- if not primary_key_column_name:
- continue
- key_columns = self.introspection.get_key_columns(cursor, table_name)
- for column_name, referenced_table_name, referenced_column_name in key_columns:
- cursor.execute("""
- SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
- LEFT JOIN `%s` as REFERRED
- ON (REFERRING.`%s` = REFERRED.`%s`)
- WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL"""
- % (primary_key_column_name, column_name, table_name, referenced_table_name,
- column_name, referenced_column_name, column_name, referenced_column_name))
- for bad_row in cursor.fetchall():
- raise utils.IntegrityError("The row in table '%s' with primary key '%s' has an invalid "
- "foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s."
- % (table_name, bad_row[0],
- table_name, column_name, bad_row[1],
- referenced_table_name, referenced_column_name))
-
- def is_usable(self):
- try:
- self.connection.ping()
- except Database.Error:
- return False
- else:
- return True
-
- @cached_property
- def mysql_version(self):
- with self.temporary_connection():
- server_info = self.connection.get_server_info()
- match = server_version_re.match(server_info)
- if not match:
- raise Exception('Unable to determine MySQL version from version string %r' % server_info)
- return tuple([int(x) for x in match.groups()])
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/client.py b/lib/python2.7/site-packages/django/db/backends/mysql/client.py
deleted file mode 100644
index 1cf8cee..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/client.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import os
-import sys
-
-from django.db.backends import BaseDatabaseClient
-
-class DatabaseClient(BaseDatabaseClient):
- executable_name = 'mysql'
-
- def runshell(self):
- settings_dict = self.connection.settings_dict
- args = [self.executable_name]
- db = settings_dict['OPTIONS'].get('db', settings_dict['NAME'])
- user = settings_dict['OPTIONS'].get('user', settings_dict['USER'])
- passwd = settings_dict['OPTIONS'].get('passwd', settings_dict['PASSWORD'])
- host = settings_dict['OPTIONS'].get('host', settings_dict['HOST'])
- port = settings_dict['OPTIONS'].get('port', settings_dict['PORT'])
- defaults_file = settings_dict['OPTIONS'].get('read_default_file')
- # Seems to be no good way to set sql_mode with CLI.
-
- if defaults_file:
- args += ["--defaults-file=%s" % defaults_file]
- if user:
- args += ["--user=%s" % user]
- if passwd:
- args += ["--password=%s" % passwd]
- if host:
- if '/' in host:
- args += ["--socket=%s" % host]
- else:
- args += ["--host=%s" % host]
- if port:
- args += ["--port=%s" % port]
- if db:
- args += [db]
-
- if os.name == 'nt':
- sys.exit(os.system(" ".join(args)))
- else:
- os.execvp(self.executable_name, args)
-
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/compiler.py b/lib/python2.7/site-packages/django/db/backends/mysql/compiler.py
deleted file mode 100644
index d3439bf..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/compiler.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from django.db.models.sql import compiler
-from django.utils.six.moves import zip_longest
-
-
-class SQLCompiler(compiler.SQLCompiler):
- def resolve_columns(self, row, fields=()):
- values = []
- index_extra_select = len(self.query.extra_select)
- for value, field in zip_longest(row[index_extra_select:], fields):
- if (field and field.get_internal_type() in ("BooleanField", "NullBooleanField") and
- value in (0, 1)):
- value = bool(value)
- values.append(value)
- return row[:index_extra_select] + tuple(values)
-
- def as_subquery_condition(self, alias, columns, qn):
- qn2 = self.connection.ops.quote_name
- sql, params = self.as_sql()
- return '(%s) IN (%s)' % (', '.join(['%s.%s' % (qn(alias), qn2(column)) for column in columns]), sql), params
-
-class SQLInsertCompiler(compiler.SQLInsertCompiler, SQLCompiler):
- pass
-
-class SQLDeleteCompiler(compiler.SQLDeleteCompiler, SQLCompiler):
- pass
-
-class SQLUpdateCompiler(compiler.SQLUpdateCompiler, SQLCompiler):
- pass
-
-class SQLAggregateCompiler(compiler.SQLAggregateCompiler, SQLCompiler):
- pass
-
-class SQLDateCompiler(compiler.SQLDateCompiler, SQLCompiler):
- pass
-
-class SQLDateTimeCompiler(compiler.SQLDateTimeCompiler, SQLCompiler):
- pass
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/creation.py b/lib/python2.7/site-packages/django/db/backends/mysql/creation.py
deleted file mode 100644
index 3a57c29..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/creation.py
+++ /dev/null
@@ -1,70 +0,0 @@
-from django.db.backends.creation import BaseDatabaseCreation
-
-class DatabaseCreation(BaseDatabaseCreation):
- # This dictionary maps Field objects to their associated MySQL column
- # types, as strings. Column-type strings can contain format strings; they'll
- # be interpolated against the values of Field.__dict__ before being output.
- # If a column type is set to None, it won't be included in the output.
- data_types = {
- 'AutoField': 'integer AUTO_INCREMENT',
- 'BinaryField': 'longblob',
- 'BooleanField': 'bool',
- 'CharField': 'varchar(%(max_length)s)',
- 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
- 'DateField': 'date',
- 'DateTimeField': 'datetime',
- 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
- 'FileField': 'varchar(%(max_length)s)',
- 'FilePathField': 'varchar(%(max_length)s)',
- 'FloatField': 'double precision',
- 'IntegerField': 'integer',
- 'BigIntegerField': 'bigint',
- 'IPAddressField': 'char(15)',
- 'GenericIPAddressField': 'char(39)',
- 'NullBooleanField': 'bool',
- 'OneToOneField': 'integer',
- 'PositiveIntegerField': 'integer UNSIGNED',
- 'PositiveSmallIntegerField': 'smallint UNSIGNED',
- 'SlugField': 'varchar(%(max_length)s)',
- 'SmallIntegerField': 'smallint',
- 'TextField': 'longtext',
- 'TimeField': 'time',
- }
-
- def sql_table_creation_suffix(self):
- suffix = []
- if self.connection.settings_dict['TEST_CHARSET']:
- suffix.append('CHARACTER SET %s' % self.connection.settings_dict['TEST_CHARSET'])
- if self.connection.settings_dict['TEST_COLLATION']:
- suffix.append('COLLATE %s' % self.connection.settings_dict['TEST_COLLATION'])
- return ' '.join(suffix)
-
- def sql_for_inline_foreign_key_references(self, model, field, known_models, style):
- "All inline references are pending under MySQL"
- return [], True
-
- def sql_destroy_indexes_for_fields(self, model, fields, style):
- if len(fields) == 1 and fields[0].db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(fields[0].db_tablespace)
- elif model._meta.db_tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
- else:
- tablespace_sql = ""
- if tablespace_sql:
- tablespace_sql = " " + tablespace_sql
-
- field_names = []
- qn = self.connection.ops.quote_name
- for f in fields:
- field_names.append(style.SQL_FIELD(qn(f.column)))
-
- index_name = "%s_%s" % (model._meta.db_table, self._digest([f.name for f in fields]))
-
- from ..util import truncate_name
-
- return [
- style.SQL_KEYWORD("DROP INDEX") + " " +
- style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + " " +
- style.SQL_KEYWORD("ON") + " " +
- style.SQL_TABLE(qn(model._meta.db_table)) + ";",
- ]
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/introspection.py b/lib/python2.7/site-packages/django/db/backends/mysql/introspection.py
deleted file mode 100644
index 548877e..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/introspection.py
+++ /dev/null
@@ -1,119 +0,0 @@
-import re
-from .base import FIELD_TYPE
-
-from django.db.backends import BaseDatabaseIntrospection, FieldInfo
-from django.utils.encoding import force_text
-
-
-foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
-
-class DatabaseIntrospection(BaseDatabaseIntrospection):
- data_types_reverse = {
- FIELD_TYPE.BLOB: 'TextField',
- FIELD_TYPE.CHAR: 'CharField',
- FIELD_TYPE.DECIMAL: 'DecimalField',
- FIELD_TYPE.NEWDECIMAL: 'DecimalField',
- FIELD_TYPE.DATE: 'DateField',
- FIELD_TYPE.DATETIME: 'DateTimeField',
- FIELD_TYPE.DOUBLE: 'FloatField',
- FIELD_TYPE.FLOAT: 'FloatField',
- FIELD_TYPE.INT24: 'IntegerField',
- FIELD_TYPE.LONG: 'IntegerField',
- FIELD_TYPE.LONGLONG: 'BigIntegerField',
- FIELD_TYPE.SHORT: 'IntegerField',
- FIELD_TYPE.STRING: 'CharField',
- FIELD_TYPE.TIME: 'TimeField',
- FIELD_TYPE.TIMESTAMP: 'DateTimeField',
- FIELD_TYPE.TINY: 'IntegerField',
- FIELD_TYPE.TINY_BLOB: 'TextField',
- FIELD_TYPE.MEDIUM_BLOB: 'TextField',
- FIELD_TYPE.LONG_BLOB: 'TextField',
- FIELD_TYPE.VAR_STRING: 'CharField',
- }
-
- def get_table_list(self, cursor):
- "Returns a list of table names in the current database."
- cursor.execute("SHOW TABLES")
- return [row[0] for row in cursor.fetchall()]
-
- def get_table_description(self, cursor, table_name):
- """
- Returns a description of the table, with the DB-API cursor.description interface."
- """
- # varchar length returned by cursor.description is an internal length,
- # not visible length (#5725), use information_schema database to fix this
- cursor.execute("""
- SELECT column_name, character_maximum_length FROM information_schema.columns
- WHERE table_name = %s AND table_schema = DATABASE()
- AND character_maximum_length IS NOT NULL""", [table_name])
- length_map = dict(cursor.fetchall())
-
- # Also getting precision and scale from information_schema (see #5014)
- cursor.execute("""
- SELECT column_name, numeric_precision, numeric_scale FROM information_schema.columns
- WHERE table_name = %s AND table_schema = DATABASE()
- AND data_type='decimal'""", [table_name])
- numeric_map = dict([(line[0], tuple([int(n) for n in line[1:]])) for line in cursor.fetchall()])
-
- cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
- return [FieldInfo(*((force_text(line[0]),)
- + line[1:3]
- + (length_map.get(line[0], line[3]),)
- + numeric_map.get(line[0], line[4:6])
- + (line[6],)))
- for line in cursor.description]
-
- def _name_to_index(self, cursor, table_name):
- """
- Returns a dictionary of {field_name: field_index} for the given table.
- Indexes are 0-based.
- """
- return dict([(d[0], i) for i, d in enumerate(self.get_table_description(cursor, table_name))])
-
- def get_relations(self, cursor, table_name):
- """
- Returns a dictionary of {field_index: (field_index_other_table, other_table)}
- representing all relationships to the given table. Indexes are 0-based.
- """
- my_field_dict = self._name_to_index(cursor, table_name)
- constraints = self.get_key_columns(cursor, table_name)
- relations = {}
- for my_fieldname, other_table, other_field in constraints:
- other_field_index = self._name_to_index(cursor, other_table)[other_field]
- my_field_index = my_field_dict[my_fieldname]
- relations[my_field_index] = (other_field_index, other_table)
- return relations
-
- def get_key_columns(self, cursor, table_name):
- """
- Returns a list of (column_name, referenced_table_name, referenced_column_name) for all
- key columns in given table.
- """
- key_columns = []
- cursor.execute("""
- SELECT column_name, referenced_table_name, referenced_column_name
- FROM information_schema.key_column_usage
- WHERE table_name = %s
- AND table_schema = DATABASE()
- AND referenced_table_name IS NOT NULL
- AND referenced_column_name IS NOT NULL""", [table_name])
- key_columns.extend(cursor.fetchall())
- return key_columns
-
- def get_indexes(self, cursor, table_name):
- cursor.execute("SHOW INDEX FROM %s" % self.connection.ops.quote_name(table_name))
- # Do a two-pass search for indexes: on first pass check which indexes
- # are multicolumn, on second pass check which single-column indexes
- # are present.
- rows = list(cursor.fetchall())
- multicol_indexes = set()
- for row in rows:
- if row[3] > 1:
- multicol_indexes.add(row[2])
- indexes = {}
- for row in rows:
- if row[2] in multicol_indexes:
- continue
- indexes[row[4]] = {'primary_key': (row[2] == 'PRIMARY'), 'unique': not bool(row[1])}
- return indexes
-
diff --git a/lib/python2.7/site-packages/django/db/backends/mysql/validation.py b/lib/python2.7/site-packages/django/db/backends/mysql/validation.py
deleted file mode 100644
index 2ce957c..0000000
--- a/lib/python2.7/site-packages/django/db/backends/mysql/validation.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from django.db.backends import BaseDatabaseValidation
-
-class DatabaseValidation(BaseDatabaseValidation):
- def validate_field(self, errors, opts, f):
- """
- MySQL has the following field length restriction:
- No character (varchar) fields can have a length exceeding 255
- characters if they have a unique index on them.
- """
- from django.db import models
- varchar_fields = (models.CharField, models.CommaSeparatedIntegerField,
- models.SlugField)
- if (isinstance(f, varchar_fields) and f.unique
- and (f.max_length is None or int(f.max_length) > 255)):
- msg = '"%(name)s": %(cls)s cannot have a "max_length" greater than 255 when using "unique=True".'
- errors.add(opts, msg % {'name': f.name, 'cls': f.__class__.__name__})
diff --git a/lib/python2.7/site-packages/django/db/backends/oracle/__init__.py b/lib/python2.7/site-packages/django/db/backends/oracle/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/lib/python2.7/site-packages/django/db/backends/oracle/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/django/db/backends/oracle/base.py b/lib/python2.7/site-packages/django/db/backends/oracle/base.py
deleted file mode 100644
index 11ab574..0000000
--- a/lib/python2.7/site-packages/django/db/backends/oracle/base.py
+++ /dev/null
@@ -1,961 +0,0 @@
-"""
-Oracle database backend for Django.
-
-Requires cx_Oracle: http://cx-oracle.sourceforge.net/
-"""
-from __future__ import unicode_literals
-
-import decimal
-import re
-import sys
-import warnings
-
-def _setup_environment(environ):
- import platform
- # Cygwin requires some special voodoo to set the environment variables
- # properly so that Oracle will see them.
- if platform.system().upper().startswith('CYGWIN'):
- try:
- import ctypes
- except ImportError as e:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("Error loading ctypes: %s; "
- "the Oracle backend requires ctypes to "
- "operate correctly under Cygwin." % e)
- kernel32 = ctypes.CDLL('kernel32')
- for name, value in environ:
- kernel32.SetEnvironmentVariableA(name, value)
- else:
- import os
- os.environ.update(environ)
-
-_setup_environment([
- # Oracle takes client-side character set encoding from the environment.
- ('NLS_LANG', '.UTF8'),
- # This prevents unicode from getting mangled by getting encoded into the
- # potentially non-unicode database character set.
- ('ORA_NCHAR_LITERAL_REPLACE', 'TRUE'),
-])
-
-
-try:
- import cx_Oracle as Database
-except ImportError as e:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("Error loading cx_Oracle module: %s" % e)
-
-try:
- import pytz
-except ImportError:
- pytz = None
-
-from django.db import utils
-from django.db.backends import *
-from django.db.backends.oracle.client import DatabaseClient
-from django.db.backends.oracle.creation import DatabaseCreation
-from django.db.backends.oracle.introspection import DatabaseIntrospection
-from django.utils.encoding import force_bytes, force_text
-
-
-DatabaseError = Database.DatabaseError
-IntegrityError = Database.IntegrityError
-
-# Check whether cx_Oracle was compiled with the WITH_UNICODE option if cx_Oracle is pre-5.1. This will
-# also be True for cx_Oracle 5.1 and in Python 3.0. See #19606
-if int(Database.version.split('.', 1)[0]) >= 5 and \
- (int(Database.version.split('.', 2)[1]) >= 1 or
- not hasattr(Database, 'UNICODE')):
- convert_unicode = force_text
-else:
- convert_unicode = force_bytes
-
-
-class DatabaseFeatures(BaseDatabaseFeatures):
- empty_fetchmany_value = ()
- needs_datetime_string_cast = False
- interprets_empty_strings_as_nulls = True
- uses_savepoints = True
- has_select_for_update = True
- has_select_for_update_nowait = True
- can_return_id_from_insert = True
- allow_sliced_subqueries = False
- supports_subqueries_in_group_by = False
- supports_transactions = True
- supports_timezones = False
- has_zoneinfo_database = pytz is not None
- supports_bitwise_or = False
- can_defer_constraint_checks = True
- ignores_nulls_in_unique_constraints = False
- has_bulk_insert = True
- supports_tablespaces = True
- supports_sequence_reset = False
- atomic_transactions = False
-
-class DatabaseOperations(BaseDatabaseOperations):
- compiler_module = "django.db.backends.oracle.compiler"
-
- def autoinc_sql(self, table, column):
- # To simulate auto-incrementing primary keys in Oracle, we have to
- # create a sequence and a trigger.
- sq_name = self._get_sequence_name(table)
- tr_name = self._get_trigger_name(table)
- tbl_name = self.quote_name(table)
- col_name = self.quote_name(column)
- sequence_sql = """
-DECLARE
- i INTEGER;
-BEGIN
- SELECT COUNT(*) INTO i FROM USER_CATALOG
- WHERE TABLE_NAME = '%(sq_name)s' AND TABLE_TYPE = 'SEQUENCE';
- IF i = 0 THEN
- EXECUTE IMMEDIATE 'CREATE SEQUENCE "%(sq_name)s"';
- END IF;
-END;
-/""" % locals()
- trigger_sql = """
-CREATE OR REPLACE TRIGGER "%(tr_name)s"
-BEFORE INSERT ON %(tbl_name)s
-FOR EACH ROW
-WHEN (new.%(col_name)s IS NULL)
- BEGIN
- SELECT "%(sq_name)s".nextval
- INTO :new.%(col_name)s FROM dual;
- END;
-/""" % locals()
- return sequence_sql, trigger_sql
-
- def cache_key_culling_sql(self):
- return """
- SELECT cache_key
- FROM (SELECT cache_key, rank() OVER (ORDER BY cache_key) AS rank FROM %s)
- WHERE rank = %%s + 1
- """
-
- def date_extract_sql(self, lookup_type, field_name):
- if lookup_type == 'week_day':
- # TO_CHAR(field, 'D') returns an integer from 1-7, where 1=Sunday.
- return "TO_CHAR(%s, 'D')" % field_name
- else:
- # http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm
- return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
-
- def date_interval_sql(self, sql, connector, timedelta):
- """
- Implements the interval functionality for expressions
- format for Oracle:
- (datefield + INTERVAL '3 00:03:20.000000' DAY(1) TO SECOND(6))
- """
- minutes, seconds = divmod(timedelta.seconds, 60)
- hours, minutes = divmod(minutes, 60)
- days = str(timedelta.days)
- day_precision = len(days)
- fmt = "(%s %s INTERVAL '%s %02d:%02d:%02d.%06d' DAY(%d) TO SECOND(6))"
- return fmt % (sql, connector, days, hours, minutes, seconds,
- timedelta.microseconds, day_precision)
-
- def date_trunc_sql(self, lookup_type, field_name):
- # http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm#i1002084
- if lookup_type in ('year', 'month'):
- return "TRUNC(%s, '%s')" % (field_name, lookup_type.upper())
- else:
- return "TRUNC(%s)" % field_name
-
- # Oracle crashes with "ORA-03113: end-of-file on communication channel"
- # if the time zone name is passed in parameter. Use interpolation instead.
- # https://groups.google.com/forum/#!msg/django-developers/zwQju7hbG78/9l934yelwfsJ
- # This regexp matches all time zone names from the zoneinfo database.
- _tzname_re = re.compile(r'^[\w/:+-]+$')
-
- def _convert_field_to_tz(self, field_name, tzname):
- if not self._tzname_re.match(tzname):
- raise ValueError("Invalid time zone name: %s" % tzname)
- # Convert from UTC to local time, returning TIMESTAMP WITH TIME ZONE.
- result = "(FROM_TZ(%s, '0:00') AT TIME ZONE '%s')" % (field_name, tzname)
- # Extracting from a TIMESTAMP WITH TIME ZONE ignore the time zone.
- # Convert to a DATETIME, which is called DATE by Oracle. There's no
- # built-in function to do that; the easiest is to go through a string.
- result = "TO_CHAR(%s, 'YYYY-MM-DD HH24:MI:SS')" % result
- result = "TO_DATE(%s, 'YYYY-MM-DD HH24:MI:SS')" % result
- # Re-convert to a TIMESTAMP because EXTRACT only handles the date part
- # on DATE values, even though they actually store the time part.
- return "CAST(%s AS TIMESTAMP)" % result
-
- def datetime_extract_sql(self, lookup_type, field_name, tzname):
- if settings.USE_TZ:
- field_name = self._convert_field_to_tz(field_name, tzname)
- if lookup_type == 'week_day':
- # TO_CHAR(field, 'D') returns an integer from 1-7, where 1=Sunday.
- sql = "TO_CHAR(%s, 'D')" % field_name
- else:
- # http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm
- sql = "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
- return sql, []
-
- def datetime_trunc_sql(self, lookup_type, field_name, tzname):
- if settings.USE_TZ:
- field_name = self._convert_field_to_tz(field_name, tzname)
- # http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm#i1002084
- if lookup_type in ('year', 'month'):
- sql = "TRUNC(%s, '%s')" % (field_name, lookup_type.upper())
- elif lookup_type == 'day':
- sql = "TRUNC(%s)" % field_name
- elif lookup_type == 'hour':
- sql = "TRUNC(%s, 'HH24')" % field_name
- elif lookup_type == 'minute':
- sql = "TRUNC(%s, 'MI')" % field_name
- else:
- sql = field_name # Cast to DATE removes sub-second precision.
- return sql, []
-
- def convert_values(self, value, field):
- if isinstance(value, Database.LOB):
- value = value.read()
- if field and field.get_internal_type() == 'TextField':
- value = force_text(value)
-
- # Oracle stores empty strings as null. We need to undo this in
- # order to adhere to the Django convention of using the empty
- # string instead of null, but only if the field accepts the
- # empty string.
- if value is None and field and field.empty_strings_allowed:
- value = ''
- # Convert 1 or 0 to True or False
- elif value in (1, 0) and field and field.get_internal_type() in ('BooleanField', 'NullBooleanField'):
- value = bool(value)
- # Force floats to the correct type
- elif value is not None and field and field.get_internal_type() == 'FloatField':
- value = float(value)
- # Convert floats to decimals
- elif value is not None and field and field.get_internal_type() == 'DecimalField':
- value = util.typecast_decimal(field.format_number(value))
- # cx_Oracle always returns datetime.datetime objects for
- # DATE and TIMESTAMP columns, but Django wants to see a
- # python datetime.date, .time, or .datetime. We use the type
- # of the Field to determine which to cast to, but it's not
- # always available.
- # As a workaround, we cast to date if all the time-related
- # values are 0, or to time if the date is 1/1/1900.
- # This could be cleaned a bit by adding a method to the Field
- # classes to normalize values from the database (the to_python
- # method is used for validation and isn't what we want here).
- elif isinstance(value, Database.Timestamp):
- if field and field.get_internal_type() == 'DateTimeField':
- pass
- elif field and field.get_internal_type() == 'DateField':
- value = value.date()
- elif field and field.get_internal_type() == 'TimeField' or (value.year == 1900 and value.month == value.day == 1):
- value = value.time()
- elif value.hour == value.minute == value.second == value.microsecond == 0:
- value = value.date()
- return value
-
- def deferrable_sql(self):
- return " DEFERRABLE INITIALLY DEFERRED"
-
- def drop_sequence_sql(self, table):
- return "DROP SEQUENCE %s;" % self.quote_name(self._get_sequence_name(table))
-
- def fetch_returned_insert_id(self, cursor):
- return int(cursor._insert_id_var.getvalue())
-
- def field_cast_sql(self, db_type, internal_type):
- if db_type and db_type.endswith('LOB'):
- return "DBMS_LOB.SUBSTR(%s)"
- else:
- return "%s"
-
- def last_executed_query(self, cursor, sql, params):
- # http://cx-oracle.sourceforge.net/html/cursor.html#Cursor.statement
- # The DB API definition does not define this attribute.
- statement = cursor.statement
- if statement and six.PY2 and not isinstance(statement, unicode):
- statement = statement.decode('utf-8')
- # Unlike Psycopg's `query` and MySQLdb`'s `_last_executed`, CxOracle's
- # `statement` doesn't contain the query parameters. refs #20010.
- return super(DatabaseOperations, self).last_executed_query(cursor, statement, params)
-
- def last_insert_id(self, cursor, table_name, pk_name):
- sq_name = self._get_sequence_name(table_name)
- cursor.execute('SELECT "%s".currval FROM dual' % sq_name)
- return cursor.fetchone()[0]
-
- def lookup_cast(self, lookup_type):
- if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith'):
- return "UPPER(%s)"
- return "%s"
-
- def max_in_list_size(self):
- return 1000
-
- def max_name_length(self):
- return 30
-
- def prep_for_iexact_query(self, x):
- return x
-
- def process_clob(self, value):
- if value is None:
- return ''
- return force_text(value.read())
-
- def quote_name(self, name):
- # SQL92 requires delimited (quoted) names to be case-sensitive. When
- # not quoted, Oracle has case-insensitive behavior for identifiers, but
- # always defaults to uppercase.
- # We simplify things by making Oracle identifiers always uppercase.
- if not name.startswith('"') and not name.endswith('"'):
- name = '"%s"' % util.truncate_name(name.upper(),
- self.max_name_length())
- # Oracle puts the query text into a (query % args) construct, so % signs
- # in names need to be escaped. The '%%' will be collapsed back to '%' at
- # that stage so we aren't really making the name longer here.
- name = name.replace('%','%%')
- return name.upper()
-
- def random_function_sql(self):
- return "DBMS_RANDOM.RANDOM"
-
- def regex_lookup_9(self, lookup_type):
- raise NotImplementedError("Regexes are not supported in Oracle before version 10g.")
-
- def regex_lookup_10(self, lookup_type):
- if lookup_type == 'regex':
- match_option = "'c'"
- else:
- match_option = "'i'"
- return 'REGEXP_LIKE(%%s, %%s, %s)' % match_option
-
- def regex_lookup(self, lookup_type):
- # If regex_lookup is called before it's been initialized, then create
- # a cursor to initialize it and recur.
- self.connection.cursor()
- return self.connection.ops.regex_lookup(lookup_type)
-
- def return_insert_id(self):
- return "RETURNING %s INTO %%s", (InsertIdVar(),)
-
- def savepoint_create_sql(self, sid):
- return convert_unicode("SAVEPOINT " + self.quote_name(sid))
-
- def savepoint_rollback_sql(self, sid):
- return convert_unicode("ROLLBACK TO SAVEPOINT " + self.quote_name(sid))
-
- def sql_flush(self, style, tables, sequences, allow_cascade=False):
- # Return a list of 'TRUNCATE x;', 'TRUNCATE y;',
- # 'TRUNCATE z;'... style SQL statements
- if tables:
- # Oracle does support TRUNCATE, but it seems to get us into
- # FK referential trouble, whereas DELETE FROM table works.
- sql = ['%s %s %s;' % (
- style.SQL_KEYWORD('DELETE'),
- style.SQL_KEYWORD('FROM'),
- style.SQL_FIELD(self.quote_name(table))
- ) for table in tables]
- # Since we've just deleted all the rows, running our sequence
- # ALTER code will reset the sequence to 0.
- sql.extend(self.sequence_reset_by_name_sql(style, sequences))
- return sql
- else:
- return []
-
- def sequence_reset_by_name_sql(self, style, sequences):
- sql = []
- for sequence_info in sequences:
- sequence_name = self._get_sequence_name(sequence_info['table'])
- table_name = self.quote_name(sequence_info['table'])
- column_name = self.quote_name(sequence_info['column'] or 'id')
- query = _get_sequence_reset_sql() % {'sequence': sequence_name,
- 'table': table_name,
- 'column': column_name}
- sql.append(query)
- return sql
-
- def sequence_reset_sql(self, style, model_list):
- from django.db import models
- output = []
- query = _get_sequence_reset_sql()
- for model in model_list:
- for f in model._meta.local_fields:
- if isinstance(f, models.AutoField):
- table_name = self.quote_name(model._meta.db_table)
- sequence_name = self._get_sequence_name(model._meta.db_table)
- column_name = self.quote_name(f.column)
- output.append(query % {'sequence': sequence_name,
- 'table': table_name,
- 'column': column_name})
- # Only one AutoField is allowed per model, so don't
- # continue to loop
- break
- for f in model._meta.many_to_many:
- if not f.rel.through:
- table_name = self.quote_name(f.m2m_db_table())
- sequence_name = self._get_sequence_name(f.m2m_db_table())
- column_name = self.quote_name('id')
- output.append(query % {'sequence': sequence_name,
- 'table': table_name,
- 'column': column_name})
- return output
-
- def start_transaction_sql(self):
- return ''
-
- def tablespace_sql(self, tablespace, inline=False):
- if inline:
- return "USING INDEX TABLESPACE %s" % self.quote_name(tablespace)
- else:
- return "TABLESPACE %s" % self.quote_name(tablespace)
-
- def value_to_db_datetime(self, value):
- if value is None:
- return None
-
- # Oracle doesn't support tz-aware datetimes
- if timezone.is_aware(value):
- if settings.USE_TZ:
- value = value.astimezone(timezone.utc).replace(tzinfo=None)
- else:
- raise ValueError("Oracle backend does not support timezone-aware datetimes when USE_TZ is False.")
-
- return six.text_type(value)
-
- def value_to_db_time(self, value):
- if value is None:
- return None
-
- if isinstance(value, six.string_types):
- return datetime.datetime.strptime(value, '%H:%M:%S')
-
- # Oracle doesn't support tz-aware times
- if timezone.is_aware(value):
- raise ValueError("Oracle backend does not support timezone-aware times.")
-
- return datetime.datetime(1900, 1, 1, value.hour, value.minute,
- value.second, value.microsecond)
-
- def year_lookup_bounds_for_date_field(self, value):
- first = '%s-01-01'
- second = '%s-12-31'
- return [first % value, second % value]
-
- def year_lookup_bounds_for_datetime_field(self, value):
- # The default implementation uses datetime objects for the bounds.
- # This must be overridden here, to use a formatted date (string) as
- # 'second' instead -- cx_Oracle chops the fraction-of-second part
- # off of datetime objects, leaving almost an entire second out of
- # the year under the default implementation.
- bounds = super(DatabaseOperations, self).year_lookup_bounds_for_datetime_field(value)
- if settings.USE_TZ:
- bounds = [b.astimezone(timezone.utc).replace(tzinfo=None) for b in bounds]
- return [b.isoformat(b' ') for b in bounds]
-
- def combine_expression(self, connector, sub_expressions):
- "Oracle requires special cases for %% and & operators in query expressions"
- if connector == '%%':
- return 'MOD(%s)' % ','.join(sub_expressions)
- elif connector == '&':
- return 'BITAND(%s)' % ','.join(sub_expressions)
- elif connector == '|':
- raise NotImplementedError("Bit-wise or is not supported in Oracle.")
- return super(DatabaseOperations, self).combine_expression(connector, sub_expressions)
-
- def _get_sequence_name(self, table):
- name_length = self.max_name_length() - 3
- return '%s_SQ' % util.truncate_name(table, name_length).upper()
-
- def _get_trigger_name(self, table):
- name_length = self.max_name_length() - 3
- return '%s_TR' % util.truncate_name(table, name_length).upper()
-
- def bulk_insert_sql(self, fields, num_values):
- items_sql = "SELECT %s FROM DUAL" % ", ".join(["%s"] * len(fields))
- return " UNION ALL ".join([items_sql] * num_values)
-
-
-class _UninitializedOperatorsDescriptor(object):
-
- def __get__(self, instance, owner):
- # If connection.operators is looked up before a connection has been
- # created, transparently initialize connection.operators to avert an
- # AttributeError.
- if instance is None:
- raise AttributeError("operators not available as class attribute")
- # Creating a cursor will initialize the operators.
- instance.cursor().close()
- return instance.__dict__['operators']
-
-
-class DatabaseWrapper(BaseDatabaseWrapper):
- vendor = 'oracle'
- operators = _UninitializedOperatorsDescriptor()
-
- _standard_operators = {
- 'exact': '= %s',
- 'iexact': '= UPPER(%s)',
- 'contains': "LIKE TRANSLATE(%s USING NCHAR_CS) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
- 'icontains': "LIKE UPPER(TRANSLATE(%s USING NCHAR_CS)) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
- 'gt': '> %s',
- 'gte': '>= %s',
- 'lt': '< %s',
- 'lte': '<= %s',
- 'startswith': "LIKE TRANSLATE(%s USING NCHAR_CS) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
- 'endswith': "LIKE TRANSLATE(%s USING NCHAR_CS) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
- 'istartswith': "LIKE UPPER(TRANSLATE(%s USING NCHAR_CS)) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
- 'iendswith': "LIKE UPPER(TRANSLATE(%s USING NCHAR_CS)) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
- }
-
- _likec_operators = _standard_operators.copy()
- _likec_operators.update({
- 'contains': "LIKEC %s ESCAPE '\\'",
- 'icontains': "LIKEC UPPER(%s) ESCAPE '\\'",
- 'startswith': "LIKEC %s ESCAPE '\\'",
- 'endswith': "LIKEC %s ESCAPE '\\'",
- 'istartswith': "LIKEC UPPER(%s) ESCAPE '\\'",
- 'iendswith': "LIKEC UPPER(%s) ESCAPE '\\'",
- })
-
- Database = Database
-
- def __init__(self, *args, **kwargs):
- super(DatabaseWrapper, self).__init__(*args, **kwargs)
-
- self.features = DatabaseFeatures(self)
- use_returning_into = self.settings_dict["OPTIONS"].get('use_returning_into', True)
- self.features.can_return_id_from_insert = use_returning_into
- self.ops = DatabaseOperations(self)
- self.client = DatabaseClient(self)
- self.creation = DatabaseCreation(self)
- self.introspection = DatabaseIntrospection(self)
- self.validation = BaseDatabaseValidation(self)
-
- def _connect_string(self):
- settings_dict = self.settings_dict
- if not settings_dict['HOST'].strip():
- settings_dict['HOST'] = 'localhost'
- if settings_dict['PORT'].strip():
- dsn = Database.makedsn(settings_dict['HOST'],
- int(settings_dict['PORT']),
- settings_dict['NAME'])
- else:
- dsn = settings_dict['NAME']
- return "%s/%s@%s" % (settings_dict['USER'],
- settings_dict['PASSWORD'], dsn)
-
- def get_connection_params(self):
- conn_params = self.settings_dict['OPTIONS'].copy()
- if 'use_returning_into' in conn_params:
- del conn_params['use_returning_into']
- return conn_params
-
- def get_new_connection(self, conn_params):
- conn_string = convert_unicode(self._connect_string())
- return Database.connect(conn_string, **conn_params)
-
- def init_connection_state(self):
- cursor = self.create_cursor()
- # Set the territory first. The territory overrides NLS_DATE_FORMAT
- # and NLS_TIMESTAMP_FORMAT to the territory default. When all of
- # these are set in single statement it isn't clear what is supposed
- # to happen.
- cursor.execute("ALTER SESSION SET NLS_TERRITORY = 'AMERICA'")
- # Set oracle date to ansi date format. This only needs to execute
- # once when we create a new connection. We also set the Territory
- # to 'AMERICA' which forces Sunday to evaluate to a '1' in
- # TO_CHAR().
- cursor.execute(
- "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
- " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'"
- + (" TIME_ZONE = 'UTC'" if settings.USE_TZ else ''))
- cursor.close()
- if 'operators' not in self.__dict__:
- # Ticket #14149: Check whether our LIKE implementation will
- # work for this connection or we need to fall back on LIKEC.
- # This check is performed only once per DatabaseWrapper
- # instance per thread, since subsequent connections will use
- # the same settings.
- cursor = self.create_cursor()
- try:
- cursor.execute("SELECT 1 FROM DUAL WHERE DUMMY %s"
- % self._standard_operators['contains'],
- ['X'])
- except DatabaseError:
- self.operators = self._likec_operators
- else:
- self.operators = self._standard_operators
- cursor.close()
-
- # There's no way for the DatabaseOperations class to know the
- # currently active Oracle version, so we do some setups here.
- # TODO: Multi-db support will need a better solution (a way to
- # communicate the current version).
- if self.oracle_version is not None and self.oracle_version <= 9:
- self.ops.regex_lookup = self.ops.regex_lookup_9
- else:
- self.ops.regex_lookup = self.ops.regex_lookup_10
-
- try:
- self.connection.stmtcachesize = 20
- except:
- # Django docs specify cx_Oracle version 4.3.1 or higher, but
- # stmtcachesize is available only in 4.3.2 and up.
- pass
-
- def create_cursor(self):
- return FormatStylePlaceholderCursor(self.connection)
-
- def _commit(self):
- if self.connection is not None:
- try:
- return self.connection.commit()
- except Database.DatabaseError as e:
- # cx_Oracle 5.0.4 raises a cx_Oracle.DatabaseError exception
- # with the following attributes and values:
- # code = 2091
- # message = 'ORA-02091: transaction rolled back
- # 'ORA-02291: integrity constraint (TEST_DJANGOTEST.SYS
- # _C00102056) violated - parent key not found'
- # We convert that particular case to our IntegrityError exception
- x = e.args[0]
- if hasattr(x, 'code') and hasattr(x, 'message') \
- and x.code == 2091 and 'ORA-02291' in x.message:
- six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
- raise
-
- # Oracle doesn't support savepoint commits. Ignore them.
- def _savepoint_commit(self, sid):
- pass
-
- def _set_autocommit(self, autocommit):
- with self.wrap_database_errors:
- self.connection.autocommit = autocommit
-
- def check_constraints(self, table_names=None):
- """
- To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they
- are returned to deferred.
- """
- self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE')
- self.cursor().execute('SET CONSTRAINTS ALL DEFERRED')
-
- def is_usable(self):
- try:
- if hasattr(self.connection, 'ping'): # Oracle 10g R2 and higher
- self.connection.ping()
- else:
- # Use a cx_Oracle cursor directly, bypassing Django's utilities.
- self.connection.cursor().execute("SELECT 1 FROM DUAL")
- except Database.Error:
- return False
- else:
- return True
-
- @cached_property
- def oracle_version(self):
- with self.temporary_connection():
- version = self.connection.version
- try:
- return int(version.split('.')[0])
- except ValueError:
- return None
-
-
-class OracleParam(object):
- """
- Wrapper object for formatting parameters for Oracle. If the string
- representation of the value is large enough (greater than 4000 characters)
- the input size needs to be set as CLOB. Alternatively, if the parameter
- has an `input_size` attribute, then the value of the `input_size` attribute
- will be used instead. Otherwise, no input size will be set for the
- parameter when executing the query.
- """
-
- def __init__(self, param, cursor, strings_only=False):
- # With raw SQL queries, datetimes can reach this function
- # without being converted by DateTimeField.get_db_prep_value.
- if settings.USE_TZ and isinstance(param, datetime.datetime):
- if timezone.is_naive(param):
- warnings.warn("Oracle received a naive datetime (%s)"
- " while time zone support is active." % param,
- RuntimeWarning)
- default_timezone = timezone.get_default_timezone()
- param = timezone.make_aware(param, default_timezone)
- param = param.astimezone(timezone.utc).replace(tzinfo=None)
-
- # Oracle doesn't recognize True and False correctly in Python 3.
- # The conversion done below works both in 2 and 3.
- if param is True:
- param = "1"
- elif param is False:
- param = "0"
- if hasattr(param, 'bind_parameter'):
- self.force_bytes = param.bind_parameter(cursor)
- elif isinstance(param, six.memoryview):
- self.force_bytes = param
- else:
- self.force_bytes = convert_unicode(param, cursor.charset,
- strings_only)
- if hasattr(param, 'input_size'):
- # If parameter has `input_size` attribute, use that.
- self.input_size = param.input_size
- elif isinstance(param, six.string_types) and len(param) > 4000:
- # Mark any string param greater than 4000 characters as a CLOB.
- self.input_size = Database.CLOB
- else:
- self.input_size = None
-
-
-class VariableWrapper(object):
- """
- An adapter class for cursor variables that prevents the wrapped object
- from being converted into a string when used to instanciate an OracleParam.
- This can be used generally for any other object that should be passed into
- Cursor.execute as-is.
- """
-
- def __init__(self, var):
- self.var = var
-
- def bind_parameter(self, cursor):
- return self.var
-
- def __getattr__(self, key):
- return getattr(self.var, key)
-
- def __setattr__(self, key, value):
- if key == 'var':
- self.__dict__[key] = value
- else:
- setattr(self.var, key, value)
-
-
-class InsertIdVar(object):
- """
- A late-binding cursor variable that can be passed to Cursor.execute
- as a parameter, in order to receive the id of the row created by an
- insert statement.
- """
-
- def bind_parameter(self, cursor):
- param = cursor.cursor.var(Database.NUMBER)
- cursor._insert_id_var = param
- return param
-
-
-class FormatStylePlaceholderCursor(object):
- """
- Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var"
- style. This fixes it -- but note that if you want to use a literal "%s" in
- a query, you'll need to use "%%s".
-
- We also do automatic conversion between Unicode on the Python side and
- UTF-8 -- for talking to Oracle -- in here.
- """
- charset = 'utf-8'
-
- def __init__(self, connection):
- self.cursor = connection.cursor()
- # Necessary to retrieve decimal values without rounding error.
- self.cursor.numbersAsStrings = True
- # Default arraysize of 1 is highly sub-optimal.
- self.cursor.arraysize = 100
-
- def _format_params(self, params):
- try:
- return dict((k,OracleParam(v, self, True)) for k,v in params.items())
- except AttributeError:
- return tuple([OracleParam(p, self, True) for p in params])
-
- def _guess_input_sizes(self, params_list):
- # Try dict handling; if that fails, treat as sequence
- if hasattr(params_list[0], 'keys'):
- sizes = {}
- for params in params_list:
- for k, value in params.items():
- if value.input_size:
- sizes[k] = value.input_size
- self.setinputsizes(**sizes)
- else:
- # It's not a list of dicts; it's a list of sequences
- sizes = [None] * len(params_list[0])
- for params in params_list:
- for i, value in enumerate(params):
- if value.input_size:
- sizes[i] = value.input_size
- self.setinputsizes(*sizes)
-
- def _param_generator(self, params):
- # Try dict handling; if that fails, treat as sequence
- if hasattr(params, 'items'):
- return dict((k, v.force_bytes) for k,v in params.items())
- else:
- return [p.force_bytes for p in params]
-
- def _fix_for_params(self, query, params):
- # cx_Oracle wants no trailing ';' for SQL statements. For PL/SQL, it
- # it does want a trailing ';' but not a trailing '/'. However, these
- # characters must be included in the original query in case the query
- # is being passed to SQL*Plus.
- if query.endswith(';') or query.endswith('/'):
- query = query[:-1]
- if params is None:
- params = []
- query = convert_unicode(query, self.charset)
- elif hasattr(params, 'keys'):
- # Handle params as dict
- args = dict((k, ":%s"%k) for k in params.keys())
- query = convert_unicode(query % args, self.charset)
- else:
- # Handle params as sequence
- args = [(':arg%d' % i) for i in range(len(params))]
- query = convert_unicode(query % tuple(args), self.charset)
- return query, self._format_params(params)
-
- def execute(self, query, params=None):
- query, params = self._fix_for_params(query, params)
- self._guess_input_sizes([params])
- try:
- return self.cursor.execute(query, self._param_generator(params))
- except Database.DatabaseError as e:
- # cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
- if hasattr(e.args[0], 'code') and e.args[0].code == 1400 and not isinstance(e, IntegrityError):
- six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
- raise
-
- def executemany(self, query, params=None):
- if not params:
- # No params given, nothing to do
- return None
- # uniform treatment for sequences and iterables
- params_iter = iter(params)
- query, firstparams = self._fix_for_params(query, next(params_iter))
- # we build a list of formatted params; as we're going to traverse it
- # more than once, we can't make it lazy by using a generator
- formatted = [firstparams]+[self._format_params(p) for p in params_iter]
- self._guess_input_sizes(formatted)
- try:
- return self.cursor.executemany(query,
- [self._param_generator(p) for p in formatted])
- except Database.DatabaseError as e:
- # cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
- if hasattr(e.args[0], 'code') and e.args[0].code == 1400 and not isinstance(e, IntegrityError):
- six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
- raise
-
- def fetchone(self):
- row = self.cursor.fetchone()
- if row is None:
- return row
- return _rowfactory(row, self.cursor)
-
- def fetchmany(self, size=None):
- if size is None:
- size = self.arraysize
- return tuple([_rowfactory(r, self.cursor)
- for r in self.cursor.fetchmany(size)])
-
- def fetchall(self):
- return tuple([_rowfactory(r, self.cursor)
- for r in self.cursor.fetchall()])
-
- def var(self, *args):
- return VariableWrapper(self.cursor.var(*args))
-
- def arrayvar(self, *args):
- return VariableWrapper(self.cursor.arrayvar(*args))
-
- def __getattr__(self, attr):
- if attr in self.__dict__:
- return self.__dict__[attr]
- else:
- return getattr(self.cursor, attr)
-
- def __iter__(self):
- return CursorIterator(self.cursor)
-
-
-class CursorIterator(six.Iterator):
-
- """Cursor iterator wrapper that invokes our custom row factory."""
-
- def __init__(self, cursor):
- self.cursor = cursor
- self.iter = iter(cursor)
-
- def __iter__(self):
- return self
-
- def __next__(self):
- return _rowfactory(next(self.iter), self.cursor)
-
-
-def _rowfactory(row, cursor):
- # Cast numeric values as the appropriate Python type based upon the
- # cursor description, and convert strings to unicode.
- casted = []
- for value, desc in zip(row, cursor.description):
- if value is not None and desc[1] is Database.NUMBER:
- precision, scale = desc[4:6]
- if scale == -127:
- if precision == 0:
- # NUMBER column: decimal-precision floating point
- # This will normally be an integer from a sequence,
- # but it could be a decimal value.
- if '.' in value:
- value = decimal.Decimal(value)
- else:
- value = int(value)
- else:
- # FLOAT column: binary-precision floating point.
- # This comes from FloatField columns.
- value = float(value)
- elif precision > 0:
- # NUMBER(p,s) column: decimal-precision fixed point.
- # This comes from IntField and DecimalField columns.
- if scale == 0:
- value = int(value)
- else:
- value = decimal.Decimal(value)
- elif '.' in value:
- # No type information. This normally comes from a
- # mathematical expression in the SELECT list. Guess int
- # or Decimal based on whether it has a decimal point.
- value = decimal.Decimal(value)
- else:
- value = int(value)
- # datetimes are returned as TIMESTAMP, except the results
- # of "dates" queries, which are returned as DATETIME.
- elif desc[1] in (Database.TIMESTAMP, Database.DATETIME):
- # Confirm that dt is naive before overwriting its tzinfo.
- if settings.USE_TZ and value is not None and timezone.is_naive(value):
- value = value.replace(tzinfo=timezone.utc)
- elif desc[1] in (Database.STRING, Database.FIXED_CHAR,
- Database.LONG_STRING):
- value = to_unicode(value)
- casted.append(value)
- return tuple(casted)
-
-
-def to_unicode(s):
- """
- Convert strings to Unicode objects (and return all other data types
- unchanged).
- """
- if isinstance(s, six.string_types):
- return force_text(s)
- return s
-
-
-def _get_sequence_reset_sql():
- # TODO: colorize this SQL code with style.SQL_KEYWORD(), etc.
- return """
-DECLARE
- table_value integer;
- seq_value integer;
-BEGIN
- SELECT NVL(MAX(%(column)s), 0) INTO table_value FROM %(table)s;
- SELECT NVL(last_number - cache_size, 0) INTO seq_value FROM user_sequences
- WHERE sequence_name = '%(sequence)s';
- WHILE table_value > seq_value LOOP
- SELECT "%(sequence)s".nextval INTO seq_value FROM dual;
- END LOOP;
-END;
-/"""
diff --git a/lib/python2.7/site-packages/django/db/backends/oracle/client.py b/lib/python2.7/site-packages/django/db/backends/oracle/client.py
deleted file mode 100644
index ccc64eb..0000000
--- a/lib/python2.7/site-packages/django/db/backends/oracle/client.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import os
-import sys
-
-from django.db.backends import BaseDatabaseClient
-
-class DatabaseClient(BaseDatabaseClient):
- executable_name = 'sqlplus'
-
- def runshell(self):
- conn_string = self.connection._connect_string()
- args = [self.executable_name, "-L", conn_string]
- if os.name == 'nt':
- sys.exit(os.system(" ".join(args)))
- else:
- os.execvp(self.executable_name, args)
-
diff --git a/lib/python2.7/site-packages/django/db/backends/oracle/compiler.py b/lib/python2.7/site-packages/django/db/backends/oracle/compiler.py
deleted file mode 100644
index bb8ef59..0000000
--- a/lib/python2.7/site-packages/django/db/backends/oracle/compiler.py
+++ /dev/null
@@ -1,72 +0,0 @@
-from django.db.models.sql import compiler
-from django.utils.six.moves import zip_longest
-
-
-class SQLCompiler(compiler.SQLCompiler):
- def resolve_columns(self, row, fields=()):
- # If this query has limit/offset information, then we expect the
- # first column to be an extra "_RN" column that we need to throw
- # away.
- if self.query.high_mark is not None or self.query.low_mark:
- rn_offset = 1
- else:
- rn_offset = 0
- index_start = rn_offset + len(self.query.extra_select)
- values = [self.query.convert_values(v, None, connection=self.connection)
- for v in row[rn_offset:index_start]]
- for value, field in zip_longest(row[index_start:], fields):
- values.append(self.query.convert_values(value, field, connection=self.connection))
- return tuple(values)
-
- def as_sql(self, with_limits=True, with_col_aliases=False):
- """
- Creates the SQL for this query. Returns the SQL string and list
- of parameters. This is overriden from the original Query class
- to handle the additional SQL Oracle requires to emulate LIMIT
- and OFFSET.
-
- If 'with_limits' is False, any limit/offset information is not
- included in the query.
- """
- if with_limits and self.query.low_mark == self.query.high_mark:
- return '', ()
-
- # The `do_offset` flag indicates whether we need to construct
- # the SQL needed to use limit/offset with Oracle.
- do_offset = with_limits and (self.query.high_mark is not None
- or self.query.low_mark)
- if not do_offset:
- sql, params = super(SQLCompiler, self).as_sql(with_limits=False,
- with_col_aliases=with_col_aliases)
- else:
- sql, params = super(SQLCompiler, self).as_sql(with_limits=False,
- with_col_aliases=True)
-
- # Wrap the base query in an outer SELECT * with boundaries on
- # the "_RN" column. This is the canonical way to emulate LIMIT
- # and OFFSET on Oracle.
- high_where = ''
- if self.query.high_mark is not None:
- high_where = 'WHERE ROWNUM <= %d' % (self.query.high_mark,)
- sql = 'SELECT * FROM (SELECT ROWNUM AS "_RN", "_SUB".* FROM (%s) "_SUB" %s) WHERE "_RN" > %d' % (sql, high_where, self.query.low_mark)
-
- return sql, params
-
-
-class SQLInsertCompiler(compiler.SQLInsertCompiler, SQLCompiler):
- pass
-
-class SQLDeleteCompiler(compiler.SQLDeleteCompiler, SQLCompiler):
- pass
-
-class SQLUpdateCompiler(compiler.SQLUpdateCompiler, SQLCompiler):
- pass
-
-class SQLAggregateCompiler(compiler.SQLAggregateCompiler, SQLCompiler):
- pass
-
-class SQLDateCompiler(compiler.SQLDateCompiler, SQLCompiler):
- pass
-
-class SQLDateTimeCompiler(compiler.SQLDateTimeCompiler, SQLCompiler):
- pass
diff --git a/lib/python2.7/site-packages/django/db/backends/oracle/creation.py b/lib/python2.7/site-packages/django/db/backends/oracle/creation.py
deleted file mode 100644
index 2f2f391..0000000
--- a/lib/python2.7/site-packages/django/db/backends/oracle/creation.py
+++ /dev/null
@@ -1,277 +0,0 @@
-import sys
-import time
-
-from django.conf import settings
-from django.db.backends.creation import BaseDatabaseCreation
-from django.utils.six.moves import input
-
-TEST_DATABASE_PREFIX = 'test_'
-PASSWORD = 'Im_a_lumberjack'
-
-class DatabaseCreation(BaseDatabaseCreation):
- # This dictionary maps Field objects to their associated Oracle column
- # types, as strings. Column-type strings can contain format strings; they'll
- # be interpolated against the values of Field.__dict__ before being output.
- # If a column type is set to None, it won't be included in the output.
- #
- # Any format strings starting with "qn_" are quoted before being used in the
- # output (the "qn_" prefix is stripped before the lookup is performed.
-
- data_types = {
- 'AutoField': 'NUMBER(11)',
- 'BinaryField': 'BLOB',
- 'BooleanField': 'NUMBER(1) CHECK (%(qn_column)s IN (0,1))',
- 'CharField': 'NVARCHAR2(%(max_length)s)',
- 'CommaSeparatedIntegerField': 'VARCHAR2(%(max_length)s)',
- 'DateField': 'DATE',
- 'DateTimeField': 'TIMESTAMP',
- 'DecimalField': 'NUMBER(%(max_digits)s, %(decimal_places)s)',
- 'FileField': 'NVARCHAR2(%(max_length)s)',
- 'FilePathField': 'NVARCHAR2(%(max_length)s)',
- 'FloatField': 'DOUBLE PRECISION',
- 'IntegerField': 'NUMBER(11)',
- 'BigIntegerField': 'NUMBER(19)',
- 'IPAddressField': 'VARCHAR2(15)',
- 'GenericIPAddressField': 'VARCHAR2(39)',
- 'NullBooleanField': 'NUMBER(1) CHECK ((%(qn_column)s IN (0,1)) OR (%(qn_column)s IS NULL))',
- 'OneToOneField': 'NUMBER(11)',
- 'PositiveIntegerField': 'NUMBER(11) CHECK (%(qn_column)s >= 0)',
- 'PositiveSmallIntegerField': 'NUMBER(11) CHECK (%(qn_column)s >= 0)',
- 'SlugField': 'NVARCHAR2(%(max_length)s)',
- 'SmallIntegerField': 'NUMBER(11)',
- 'TextField': 'NCLOB',
- 'TimeField': 'TIMESTAMP',
- 'URLField': 'VARCHAR2(%(max_length)s)',
- }
-
- def __init__(self, connection):
- super(DatabaseCreation, self).__init__(connection)
-
- def _create_test_db(self, verbosity=1, autoclobber=False):
- TEST_NAME = self._test_database_name()
- TEST_USER = self._test_database_user()
- TEST_PASSWD = self._test_database_passwd()
- TEST_TBLSPACE = self._test_database_tblspace()
- TEST_TBLSPACE_TMP = self._test_database_tblspace_tmp()
-
- parameters = {
- 'dbname': TEST_NAME,
- 'user': TEST_USER,
- 'password': TEST_PASSWD,
- 'tblspace': TEST_TBLSPACE,
- 'tblspace_temp': TEST_TBLSPACE_TMP,
- }
-
- cursor = self.connection.cursor()
- if self._test_database_create():
- try:
- self._execute_test_db_creation(cursor, parameters, verbosity)
- except Exception as e:
- sys.stderr.write("Got an error creating the test database: %s\n" % e)
- if not autoclobber:
- confirm = input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_NAME)
- if autoclobber or confirm == 'yes':
- try:
- if verbosity >= 1:
- print("Destroying old test database '%s'..." % self.connection.alias)
- self._execute_test_db_destruction(cursor, parameters, verbosity)
- self._execute_test_db_creation(cursor, parameters, verbosity)
- except Exception as e:
- sys.stderr.write("Got an error recreating the test database: %s\n" % e)
- sys.exit(2)
- else:
- print("Tests cancelled.")
- sys.exit(1)
-
- if self._test_user_create():
- if verbosity >= 1:
- print("Creating test user...")
- try:
- self._create_test_user(cursor, parameters, verbosity)
- except Exception as e:
- sys.stderr.write("Got an error creating the test user: %s\n" % e)
- if not autoclobber:
- confirm = input("It appears the test user, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_USER)
- if autoclobber or confirm == 'yes':
- try:
- if verbosity >= 1:
- print("Destroying old test user...")
- self._destroy_test_user(cursor, parameters, verbosity)
- if verbosity >= 1:
- print("Creating test user...")
- self._create_test_user(cursor, parameters, verbosity)
- except Exception as e:
- sys.stderr.write("Got an error recreating the test user: %s\n" % e)
- sys.exit(2)
- else:
- print("Tests cancelled.")
- sys.exit(1)
-
- real_settings = settings.DATABASES[self.connection.alias]
- real_settings['SAVED_USER'] = self.connection.settings_dict['SAVED_USER'] = self.connection.settings_dict['USER']
- real_settings['SAVED_PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD'] = self.connection.settings_dict['PASSWORD']
- real_settings['TEST_USER'] = real_settings['USER'] = self.connection.settings_dict['TEST_USER'] = self.connection.settings_dict['USER'] = TEST_USER
- real_settings['PASSWORD'] = self.connection.settings_dict['PASSWORD'] = TEST_PASSWD
-
- return self.connection.settings_dict['NAME']
-
- def _destroy_test_db(self, test_database_name, verbosity=1):
- """
- Destroy a test database, prompting the user for confirmation if the
- database already exists. Returns the name of the test database created.
- """
- TEST_NAME = self._test_database_name()
- TEST_USER = self._test_database_user()
- TEST_PASSWD = self._test_database_passwd()
- TEST_TBLSPACE = self._test_database_tblspace()
- TEST_TBLSPACE_TMP = self._test_database_tblspace_tmp()
-
- self.connection.settings_dict['USER'] = self.connection.settings_dict['SAVED_USER']
- self.connection.settings_dict['PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD']
-
- parameters = {
- 'dbname': TEST_NAME,
- 'user': TEST_USER,
- 'password': TEST_PASSWD,
- 'tblspace': TEST_TBLSPACE,
- 'tblspace_temp': TEST_TBLSPACE_TMP,
- }
-
- cursor = self.connection.cursor()
- time.sleep(1) # To avoid "database is being accessed by other users" errors.
- if self._test_user_create():
- if verbosity >= 1:
- print('Destroying test user...')
- self._destroy_test_user(cursor, parameters, verbosity)
- if self._test_database_create():
- if verbosity >= 1:
- print('Destroying test database tables...')
- self._execute_test_db_destruction(cursor, parameters, verbosity)
- self.connection.close()
-
- def _execute_test_db_creation(self, cursor, parameters, verbosity):
- if verbosity >= 2:
- print("_create_test_db(): dbname = %s" % parameters['dbname'])
- statements = [
- """CREATE TABLESPACE %(tblspace)s
- DATAFILE '%(tblspace)s.dbf' SIZE 20M
- REUSE AUTOEXTEND ON NEXT 10M MAXSIZE 200M
- """,
- """CREATE TEMPORARY TABLESPACE %(tblspace_temp)s
- TEMPFILE '%(tblspace_temp)s.dbf' SIZE 20M
- REUSE AUTOEXTEND ON NEXT 10M MAXSIZE 100M
- """,
- ]
- self._execute_statements(cursor, statements, parameters, verbosity)
-
- def _create_test_user(self, cursor, parameters, verbosity):
- if verbosity >= 2:
- print("_create_test_user(): username = %s" % parameters['user'])
- statements = [
- """CREATE USER %(user)s
- IDENTIFIED BY %(password)s
- DEFAULT TABLESPACE %(tblspace)s
- TEMPORARY TABLESPACE %(tblspace_temp)s
- QUOTA UNLIMITED ON %(tblspace)s
- """,
- """GRANT CONNECT, RESOURCE TO %(user)s""",
- ]
- self._execute_statements(cursor, statements, parameters, verbosity)
-
- def _execute_test_db_destruction(self, cursor, parameters, verbosity):
- if verbosity >= 2:
- print("_execute_test_db_destruction(): dbname=%s" % parameters['dbname'])
- statements = [
- 'DROP TABLESPACE %(tblspace)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS',
- 'DROP TABLESPACE %(tblspace_temp)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS',
- ]
- self._execute_statements(cursor, statements, parameters, verbosity)
-
- def _destroy_test_user(self, cursor, parameters, verbosity):
- if verbosity >= 2:
- print("_destroy_test_user(): user=%s" % parameters['user'])
- print("Be patient. This can take some time...")
- statements = [
- 'DROP USER %(user)s CASCADE',
- ]
- self._execute_statements(cursor, statements, parameters, verbosity)
-
- def _execute_statements(self, cursor, statements, parameters, verbosity):
- for template in statements:
- stmt = template % parameters
- if verbosity >= 2:
- print(stmt)
- try:
- cursor.execute(stmt)
- except Exception as err:
- sys.stderr.write("Failed (%s)\n" % (err))
- raise
-
- def _test_database_name(self):
- name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
- try:
- if self.connection.settings_dict['TEST_NAME']:
- name = self.connection.settings_dict['TEST_NAME']
- except AttributeError:
- pass
- return name
-
- def _test_database_create(self):
- return self.connection.settings_dict.get('TEST_CREATE', True)
-
- def _test_user_create(self):
- return self.connection.settings_dict.get('TEST_USER_CREATE', True)
-
- def _test_database_user(self):
- name = TEST_DATABASE_PREFIX + self.connection.settings_dict['USER']
- try:
- if self.connection.settings_dict['TEST_USER']:
- name = self.connection.settings_dict['TEST_USER']
- except KeyError:
- pass
- return name
-
- def _test_database_passwd(self):
- name = PASSWORD
- try:
- if self.connection.settings_dict['TEST_PASSWD']:
- name = self.connection.settings_dict['TEST_PASSWD']
- except KeyError:
- pass
- return name
-
- def _test_database_tblspace(self):
- name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME']
- try:
- if self.connection.settings_dict['TEST_TBLSPACE']:
- name = self.connection.settings_dict['TEST_TBLSPACE']
- except KeyError:
- pass
- return name
-
- def _test_database_tblspace_tmp(self):
- name = TEST_DATABASE_PREFIX + self.connection.settings_dict['NAME'] + '_temp'
- try:
- if self.connection.settings_dict['TEST_TBLSPACE_TMP']:
- name = self.connection.settings_dict['TEST_TBLSPACE_TMP']
- except KeyError:
- pass
- return name
-
- def _get_test_db_name(self):
- """
- We need to return the 'production' DB name to get the test DB creation
- machinery to work. This isn't a great deal in this case because DB
- names as handled by Django haven't real counterparts in Oracle.
- """
- return self.connection.settings_dict['NAME']
-
- def test_db_signature(self):
- settings_dict = self.connection.settings_dict
- return (
- settings_dict['HOST'],
- settings_dict['PORT'],
- settings_dict['ENGINE'],
- settings_dict['NAME'],
- self._test_database_user(),
- )
diff --git a/lib/python2.7/site-packages/django/db/backends/oracle/introspection.py b/lib/python2.7/site-packages/django/db/backends/oracle/introspection.py
deleted file mode 100644
index 3ea3a08..0000000
--- a/lib/python2.7/site-packages/django/db/backends/oracle/introspection.py
+++ /dev/null
@@ -1,138 +0,0 @@
-from django.db.backends import BaseDatabaseIntrospection, FieldInfo
-from django.utils.encoding import force_text
-import cx_Oracle
-import re
-
-foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
-
-class DatabaseIntrospection(BaseDatabaseIntrospection):
- # Maps type objects to Django Field types.
- data_types_reverse = {
- cx_Oracle.BLOB: 'BinaryField',
- cx_Oracle.CLOB: 'TextField',
- cx_Oracle.DATETIME: 'DateField',
- cx_Oracle.FIXED_CHAR: 'CharField',
- cx_Oracle.NCLOB: 'TextField',
- cx_Oracle.NUMBER: 'DecimalField',
- cx_Oracle.STRING: 'CharField',
- cx_Oracle.TIMESTAMP: 'DateTimeField',
- }
-
- try:
- data_types_reverse[cx_Oracle.NATIVE_FLOAT] = 'FloatField'
- except AttributeError:
- pass
-
- try:
- data_types_reverse[cx_Oracle.UNICODE] = 'CharField'
- except AttributeError:
- pass
-
- def get_field_type(self, data_type, description):
- # If it's a NUMBER with scale == 0, consider it an IntegerField
- if data_type == cx_Oracle.NUMBER:
- precision, scale = description[4:6]
- if scale == 0:
- if precision > 11:
- return 'BigIntegerField'
- elif precision == 1:
- return 'BooleanField'
- else:
- return 'IntegerField'
- elif scale == -127:
- return 'FloatField'
-
- return super(DatabaseIntrospection, self).get_field_type(data_type, description)
-
- def get_table_list(self, cursor):
- "Returns a list of table names in the current database."
- cursor.execute("SELECT TABLE_NAME FROM USER_TABLES")
- return [row[0].lower() for row in cursor.fetchall()]
-
- def get_table_description(self, cursor, table_name):
- "Returns a description of the table, with the DB-API cursor.description interface."
- cursor.execute("SELECT * FROM %s WHERE ROWNUM < 2" % self.connection.ops.quote_name(table_name))
- description = []
- for desc in cursor.description:
- name = force_text(desc[0]) # cx_Oracle always returns a 'str' on both Python 2 and 3
- name = name % {} # cx_Oracle, for some reason, doubles percent signs.
- description.append(FieldInfo(*(name.lower(),) + desc[1:]))
- return description
-
- def table_name_converter(self, name):
- "Table name comparison is case insensitive under Oracle"
- return name.lower()
-
- def _name_to_index(self, cursor, table_name):
- """
- Returns a dictionary of {field_name: field_index} for the given table.
- Indexes are 0-based.
- """
- return dict([(d[0], i) for i, d in enumerate(self.get_table_description(cursor, table_name))])
-
- def get_relations(self, cursor, table_name):
- """
- Returns a dictionary of {field_index: (field_index_other_table, other_table)}
- representing all relationships to the given table. Indexes are 0-based.
- """
- table_name = table_name.upper()
- cursor.execute("""
- SELECT ta.column_id - 1, tb.table_name, tb.column_id - 1
- FROM user_constraints, USER_CONS_COLUMNS ca, USER_CONS_COLUMNS cb,
- user_tab_cols ta, user_tab_cols tb
- WHERE user_constraints.table_name = %s AND
- ta.table_name = user_constraints.table_name AND
- ta.column_name = ca.column_name AND
- ca.table_name = ta.table_name AND
- user_constraints.constraint_name = ca.constraint_name AND
- user_constraints.r_constraint_name = cb.constraint_name AND
- cb.table_name = tb.table_name AND
- cb.column_name = tb.column_name AND
- ca.position = cb.position""", [table_name])
-
- relations = {}
- for row in cursor.fetchall():
- relations[row[0]] = (row[2], row[1].lower())
- return relations
-
- def get_key_columns(self, cursor, table_name):
- cursor.execute("""
- SELECT ccol.column_name, rcol.table_name AS referenced_table, rcol.column_name AS referenced_column
- FROM user_constraints c
- JOIN user_cons_columns ccol
- ON ccol.constraint_name = c.constraint_name
- JOIN user_cons_columns rcol
- ON rcol.constraint_name = c.r_constraint_name
- WHERE c.table_name = %s AND c.constraint_type = 'R'""" , [table_name.upper()])
- return [tuple(cell.lower() for cell in row)
- for row in cursor.fetchall()]
-
- def get_indexes(self, cursor, table_name):
- sql = """
- SELECT LOWER(uic1.column_name) AS column_name,
- CASE user_constraints.constraint_type
- WHEN 'P' THEN 1 ELSE 0
- END AS is_primary_key,
- CASE user_indexes.uniqueness
- WHEN 'UNIQUE' THEN 1 ELSE 0
- END AS is_unique
- FROM user_constraints, user_indexes, user_ind_columns uic1
- WHERE user_constraints.constraint_type (+) = 'P'
- AND user_constraints.index_name (+) = uic1.index_name
- AND user_indexes.uniqueness (+) = 'UNIQUE'
- AND user_indexes.index_name (+) = uic1.index_name
- AND uic1.table_name = UPPER(%s)
- AND uic1.column_position = 1
- AND NOT EXISTS (
- SELECT 1
- FROM user_ind_columns uic2
- WHERE uic2.index_name = uic1.index_name
- AND uic2.column_position = 2
- )
- """
- cursor.execute(sql, [table_name])
- indexes = {}
- for row in cursor.fetchall():
- indexes[row[0]] = {'primary_key': bool(row[1]),
- 'unique': bool(row[2])}
- return indexes
diff --git a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/__init__.py b/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py b/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py
deleted file mode 100644
index 9aa8b47..0000000
--- a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py
+++ /dev/null
@@ -1,184 +0,0 @@
-"""
-PostgreSQL database backend for Django.
-
-Requires psycopg 2: http://initd.org/projects/psycopg2
-"""
-
-import sys
-
-from django.db.backends import *
-from django.db.backends.postgresql_psycopg2.operations import DatabaseOperations
-from django.db.backends.postgresql_psycopg2.client import DatabaseClient
-from django.db.backends.postgresql_psycopg2.creation import DatabaseCreation
-from django.db.backends.postgresql_psycopg2.version import get_version
-from django.db.backends.postgresql_psycopg2.introspection import DatabaseIntrospection
-from django.utils.encoding import force_str
-from django.utils.functional import cached_property
-from django.utils.safestring import SafeText, SafeBytes
-from django.utils.timezone import utc
-
-try:
- import psycopg2 as Database
- import psycopg2.extensions
-except ImportError as e:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("Error loading psycopg2 module: %s" % e)
-
-DatabaseError = Database.DatabaseError
-IntegrityError = Database.IntegrityError
-
-psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
-psycopg2.extensions.register_adapter(SafeBytes, psycopg2.extensions.QuotedString)
-psycopg2.extensions.register_adapter(SafeText, psycopg2.extensions.QuotedString)
-
-def utc_tzinfo_factory(offset):
- if offset != 0:
- raise AssertionError("database connection isn't set to UTC")
- return utc
-
-class DatabaseFeatures(BaseDatabaseFeatures):
- needs_datetime_string_cast = False
- can_return_id_from_insert = True
- requires_rollback_on_dirty_transaction = True
- has_real_datatype = True
- can_defer_constraint_checks = True
- has_select_for_update = True
- has_select_for_update_nowait = True
- has_bulk_insert = True
- uses_savepoints = True
- supports_tablespaces = True
- supports_transactions = True
- can_distinct_on_fields = True
-
-class DatabaseWrapper(BaseDatabaseWrapper):
- vendor = 'postgresql'
- operators = {
- 'exact': '= %s',
- 'iexact': '= UPPER(%s)',
- 'contains': 'LIKE %s',
- 'icontains': 'LIKE UPPER(%s)',
- 'regex': '~ %s',
- 'iregex': '~* %s',
- 'gt': '> %s',
- 'gte': '>= %s',
- 'lt': '< %s',
- 'lte': '<= %s',
- 'startswith': 'LIKE %s',
- 'endswith': 'LIKE %s',
- 'istartswith': 'LIKE UPPER(%s)',
- 'iendswith': 'LIKE UPPER(%s)',
- }
-
- Database = Database
-
- def __init__(self, *args, **kwargs):
- super(DatabaseWrapper, self).__init__(*args, **kwargs)
-
- opts = self.settings_dict["OPTIONS"]
- RC = psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED
- self.isolation_level = opts.get('isolation_level', RC)
-
- self.features = DatabaseFeatures(self)
- self.ops = DatabaseOperations(self)
- self.client = DatabaseClient(self)
- self.creation = DatabaseCreation(self)
- self.introspection = DatabaseIntrospection(self)
- self.validation = BaseDatabaseValidation(self)
-
- def get_connection_params(self):
- settings_dict = self.settings_dict
- if not settings_dict['NAME']:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured(
- "settings.DATABASES is improperly configured. "
- "Please supply the NAME value.")
- conn_params = {
- 'database': settings_dict['NAME'],
- }
- conn_params.update(settings_dict['OPTIONS'])
- if 'autocommit' in conn_params:
- del conn_params['autocommit']
- if 'isolation_level' in conn_params:
- del conn_params['isolation_level']
- if settings_dict['USER']:
- conn_params['user'] = settings_dict['USER']
- if settings_dict['PASSWORD']:
- conn_params['password'] = force_str(settings_dict['PASSWORD'])
- if settings_dict['HOST']:
- conn_params['host'] = settings_dict['HOST']
- if settings_dict['PORT']:
- conn_params['port'] = settings_dict['PORT']
- return conn_params
-
- def get_new_connection(self, conn_params):
- return Database.connect(**conn_params)
-
- def init_connection_state(self):
- settings_dict = self.settings_dict
- self.connection.set_client_encoding('UTF8')
- tz = 'UTC' if settings.USE_TZ else settings_dict.get('TIME_ZONE')
- if tz:
- try:
- get_parameter_status = self.connection.get_parameter_status
- except AttributeError:
- # psycopg2 < 2.0.12 doesn't have get_parameter_status
- conn_tz = None
- else:
- conn_tz = get_parameter_status('TimeZone')
-
- if conn_tz != tz:
- self.connection.cursor().execute(
- self.ops.set_time_zone_sql(), [tz])
- # Commit after setting the time zone (see #17062)
- self.connection.commit()
- self.connection.set_isolation_level(self.isolation_level)
-
- def create_cursor(self):
- cursor = self.connection.cursor()
- cursor.tzinfo_factory = utc_tzinfo_factory if settings.USE_TZ else None
- return cursor
-
- def _set_isolation_level(self, isolation_level):
- assert isolation_level in range(1, 5) # Use set_autocommit for level = 0
- if self.psycopg2_version >= (2, 4, 2):
- self.connection.set_session(isolation_level=isolation_level)
- else:
- self.connection.set_isolation_level(isolation_level)
-
- def _set_autocommit(self, autocommit):
- with self.wrap_database_errors:
- if self.psycopg2_version >= (2, 4, 2):
- self.connection.autocommit = autocommit
- else:
- if autocommit:
- level = psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT
- else:
- level = self.isolation_level
- self.connection.set_isolation_level(level)
-
- def check_constraints(self, table_names=None):
- """
- To check constraints, we set constraints to immediate. Then, when, we're done we must ensure they
- are returned to deferred.
- """
- self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE')
- self.cursor().execute('SET CONSTRAINTS ALL DEFERRED')
-
- def is_usable(self):
- try:
- # Use a psycopg cursor directly, bypassing Django's utilities.
- self.connection.cursor().execute("SELECT 1")
- except Database.Error:
- return False
- else:
- return True
-
- @cached_property
- def psycopg2_version(self):
- version = psycopg2.__version__.split(' ', 1)[0]
- return tuple(int(v) for v in version.split('.'))
-
- @cached_property
- def pg_version(self):
- with self.temporary_connection():
- return get_version(self.connection)
diff --git a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/client.py b/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/client.py
deleted file mode 100644
index a5c0296..0000000
--- a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/client.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import os
-import sys
-
-from django.db.backends import BaseDatabaseClient
-
-class DatabaseClient(BaseDatabaseClient):
- executable_name = 'psql'
-
- def runshell(self):
- settings_dict = self.connection.settings_dict
- args = [self.executable_name]
- if settings_dict['USER']:
- args += ["-U", settings_dict['USER']]
- if settings_dict['HOST']:
- args.extend(["-h", settings_dict['HOST']])
- if settings_dict['PORT']:
- args.extend(["-p", str(settings_dict['PORT'])])
- args += [settings_dict['NAME']]
- if os.name == 'nt':
- sys.exit(os.system(" ".join(args)))
- else:
- os.execvp(self.executable_name, args)
-
diff --git a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/creation.py b/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/creation.py
deleted file mode 100644
index d4260e0..0000000
--- a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/creation.py
+++ /dev/null
@@ -1,77 +0,0 @@
-from django.db.backends.creation import BaseDatabaseCreation
-from django.db.backends.util import truncate_name
-
-
-class DatabaseCreation(BaseDatabaseCreation):
- # This dictionary maps Field objects to their associated PostgreSQL column
- # types, as strings. Column-type strings can contain format strings; they'll
- # be interpolated against the values of Field.__dict__ before being output.
- # If a column type is set to None, it won't be included in the output.
- data_types = {
- 'AutoField': 'serial',
- 'BinaryField': 'bytea',
- 'BooleanField': 'boolean',
- 'CharField': 'varchar(%(max_length)s)',
- 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
- 'DateField': 'date',
- 'DateTimeField': 'timestamp with time zone',
- 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
- 'FileField': 'varchar(%(max_length)s)',
- 'FilePathField': 'varchar(%(max_length)s)',
- 'FloatField': 'double precision',
- 'IntegerField': 'integer',
- 'BigIntegerField': 'bigint',
- 'IPAddressField': 'inet',
- 'GenericIPAddressField': 'inet',
- 'NullBooleanField': 'boolean',
- 'OneToOneField': 'integer',
- 'PositiveIntegerField': 'integer CHECK ("%(column)s" >= 0)',
- 'PositiveSmallIntegerField': 'smallint CHECK ("%(column)s" >= 0)',
- 'SlugField': 'varchar(%(max_length)s)',
- 'SmallIntegerField': 'smallint',
- 'TextField': 'text',
- 'TimeField': 'time',
- }
-
- def sql_table_creation_suffix(self):
- assert self.connection.settings_dict['TEST_COLLATION'] is None, "PostgreSQL does not support collation setting at database creation time."
- if self.connection.settings_dict['TEST_CHARSET']:
- return "WITH ENCODING '%s'" % self.connection.settings_dict['TEST_CHARSET']
- return ''
-
- def sql_indexes_for_field(self, model, f, style):
- output = []
- if f.db_index or f.unique:
- qn = self.connection.ops.quote_name
- db_table = model._meta.db_table
- tablespace = f.db_tablespace or model._meta.db_tablespace
- if tablespace:
- tablespace_sql = self.connection.ops.tablespace_sql(tablespace)
- if tablespace_sql:
- tablespace_sql = ' ' + tablespace_sql
- else:
- tablespace_sql = ''
-
- def get_index_sql(index_name, opclass=''):
- return (style.SQL_KEYWORD('CREATE INDEX') + ' ' +
- style.SQL_TABLE(qn(truncate_name(index_name,self.connection.ops.max_name_length()))) + ' ' +
- style.SQL_KEYWORD('ON') + ' ' +
- style.SQL_TABLE(qn(db_table)) + ' ' +
- "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) +
- "%s;" % tablespace_sql)
-
- if not f.unique:
- output = [get_index_sql('%s_%s' % (db_table, f.column))]
-
- # Fields with database column types of `varchar` and `text` need
- # a second index that specifies their operator class, which is
- # needed when performing correct LIKE queries outside the
- # C locale. See #12234.
- db_type = f.db_type(connection=self.connection)
- if db_type.startswith('varchar'):
- output.append(get_index_sql('%s_%s_like' % (db_table, f.column),
- ' varchar_pattern_ops'))
- elif db_type.startswith('text'):
- output.append(get_index_sql('%s_%s_like' % (db_table, f.column),
- ' text_pattern_ops'))
- return output
diff --git a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/introspection.py b/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/introspection.py
deleted file mode 100644
index ea4e3e1..0000000
--- a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/introspection.py
+++ /dev/null
@@ -1,111 +0,0 @@
-from __future__ import unicode_literals
-
-from django.db.backends import BaseDatabaseIntrospection, FieldInfo
-from django.utils.encoding import force_text
-
-
-class DatabaseIntrospection(BaseDatabaseIntrospection):
- # Maps type codes to Django Field types.
- data_types_reverse = {
- 16: 'BooleanField',
- 17: 'BinaryField',
- 20: 'BigIntegerField',
- 21: 'SmallIntegerField',
- 23: 'IntegerField',
- 25: 'TextField',
- 700: 'FloatField',
- 701: 'FloatField',
- 869: 'GenericIPAddressField',
- 1042: 'CharField', # blank-padded
- 1043: 'CharField',
- 1082: 'DateField',
- 1083: 'TimeField',
- 1114: 'DateTimeField',
- 1184: 'DateTimeField',
- 1266: 'TimeField',
- 1700: 'DecimalField',
- }
-
- ignored_tables = []
-
- def get_table_list(self, cursor):
- "Returns a list of table names in the current database."
- cursor.execute("""
- SELECT c.relname
- FROM pg_catalog.pg_class c
- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
- WHERE c.relkind IN ('r', 'v', '')
- AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
- AND pg_catalog.pg_table_is_visible(c.oid)""")
- return [row[0] for row in cursor.fetchall() if row[0] not in self.ignored_tables]
-
- def get_table_description(self, cursor, table_name):
- "Returns a description of the table, with the DB-API cursor.description interface."
- # As cursor.description does not return reliably the nullable property,
- # we have to query the information_schema (#7783)
- cursor.execute("""
- SELECT column_name, is_nullable
- FROM information_schema.columns
- WHERE table_name = %s""", [table_name])
- null_map = dict(cursor.fetchall())
- cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
- return [FieldInfo(*((force_text(line[0]),) + line[1:6] + (null_map[force_text(line[0])]=='YES',)))
- for line in cursor.description]
-
- def get_relations(self, cursor, table_name):
- """
- Returns a dictionary of {field_index: (field_index_other_table, other_table)}
- representing all relationships to the given table. Indexes are 0-based.
- """
- cursor.execute("""
- SELECT con.conkey, con.confkey, c2.relname
- FROM pg_constraint con, pg_class c1, pg_class c2
- WHERE c1.oid = con.conrelid
- AND c2.oid = con.confrelid
- AND c1.relname = %s
- AND con.contype = 'f'""", [table_name])
- relations = {}
- for row in cursor.fetchall():
- # row[0] and row[1] are single-item lists, so grab the single item.
- relations[row[0][0] - 1] = (row[1][0] - 1, row[2])
- return relations
-
- def get_key_columns(self, cursor, table_name):
- key_columns = []
- cursor.execute("""
- SELECT kcu.column_name, ccu.table_name AS referenced_table, ccu.column_name AS referenced_column
- FROM information_schema.constraint_column_usage ccu
- LEFT JOIN information_schema.key_column_usage kcu
- ON ccu.constraint_catalog = kcu.constraint_catalog
- AND ccu.constraint_schema = kcu.constraint_schema
- AND ccu.constraint_name = kcu.constraint_name
- LEFT JOIN information_schema.table_constraints tc
- ON ccu.constraint_catalog = tc.constraint_catalog
- AND ccu.constraint_schema = tc.constraint_schema
- AND ccu.constraint_name = tc.constraint_name
- WHERE kcu.table_name = %s AND tc.constraint_type = 'FOREIGN KEY'""" , [table_name])
- key_columns.extend(cursor.fetchall())
- return key_columns
-
- def get_indexes(self, cursor, table_name):
- # This query retrieves each index on the given table, including the
- # first associated field name
- cursor.execute("""
- SELECT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary
- FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,
- pg_catalog.pg_index idx, pg_catalog.pg_attribute attr
- WHERE c.oid = idx.indrelid
- AND idx.indexrelid = c2.oid
- AND attr.attrelid = c.oid
- AND attr.attnum = idx.indkey[0]
- AND c.relname = %s""", [table_name])
- indexes = {}
- for row in cursor.fetchall():
- # row[1] (idx.indkey) is stored in the DB as an array. It comes out as
- # a string of space-separated integers. This designates the field
- # indexes (1-based) of the fields that have indexes on the table.
- # Here, we skip any indexes across multiple fields.
- if ' ' in row[1]:
- continue
- indexes[row[0]] = {'primary_key': row[3], 'unique': row[2]}
- return indexes
diff --git a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/operations.py b/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/operations.py
deleted file mode 100644
index c5aab84..0000000
--- a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/operations.py
+++ /dev/null
@@ -1,222 +0,0 @@
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.db.backends import BaseDatabaseOperations
-
-
-class DatabaseOperations(BaseDatabaseOperations):
- def __init__(self, connection):
- super(DatabaseOperations, self).__init__(connection)
-
- def date_extract_sql(self, lookup_type, field_name):
- # http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
- if lookup_type == 'week_day':
- # For consistency across backends, we return Sunday=1, Saturday=7.
- return "EXTRACT('dow' FROM %s) + 1" % field_name
- else:
- return "EXTRACT('%s' FROM %s)" % (lookup_type, field_name)
-
- def date_interval_sql(self, sql, connector, timedelta):
- """
- implements the interval functionality for expressions
- format for Postgres:
- (datefield + interval '3 days 200 seconds 5 microseconds')
- """
- modifiers = []
- if timedelta.days:
- modifiers.append('%s days' % timedelta.days)
- if timedelta.seconds:
- modifiers.append('%s seconds' % timedelta.seconds)
- if timedelta.microseconds:
- modifiers.append('%s microseconds' % timedelta.microseconds)
- mods = ' '.join(modifiers)
- conn = ' %s ' % connector
- return '(%s)' % conn.join([sql, 'interval \'%s\'' % mods])
-
- def date_trunc_sql(self, lookup_type, field_name):
- # http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
- return "DATE_TRUNC('%s', %s)" % (lookup_type, field_name)
-
- def datetime_extract_sql(self, lookup_type, field_name, tzname):
- if settings.USE_TZ:
- field_name = "%s AT TIME ZONE %%s" % field_name
- params = [tzname]
- else:
- params = []
- # http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
- if lookup_type == 'week_day':
- # For consistency across backends, we return Sunday=1, Saturday=7.
- sql = "EXTRACT('dow' FROM %s) + 1" % field_name
- else:
- sql = "EXTRACT('%s' FROM %s)" % (lookup_type, field_name)
- return sql, params
-
- def datetime_trunc_sql(self, lookup_type, field_name, tzname):
- if settings.USE_TZ:
- field_name = "%s AT TIME ZONE %%s" % field_name
- params = [tzname]
- else:
- params = []
- # http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
- sql = "DATE_TRUNC('%s', %s)" % (lookup_type, field_name)
- return sql, params
-
- def deferrable_sql(self):
- return " DEFERRABLE INITIALLY DEFERRED"
-
- def lookup_cast(self, lookup_type):
- lookup = '%s'
-
- # Cast text lookups to text to allow things like filter(x__contains=4)
- if lookup_type in ('iexact', 'contains', 'icontains', 'startswith',
- 'istartswith', 'endswith', 'iendswith', 'regex', 'iregex'):
- lookup = "%s::text"
-
- # Use UPPER(x) for case-insensitive lookups; it's faster.
- if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith'):
- lookup = 'UPPER(%s)' % lookup
-
- return lookup
-
- def field_cast_sql(self, db_type, internal_type):
- if internal_type == "GenericIPAddressField" or internal_type == "IPAddressField":
- return 'HOST(%s)'
- return '%s'
-
- def last_insert_id(self, cursor, table_name, pk_name):
- # Use pg_get_serial_sequence to get the underlying sequence name
- # from the table name and column name (available since PostgreSQL 8)
- cursor.execute("SELECT CURRVAL(pg_get_serial_sequence('%s','%s'))" % (
- self.quote_name(table_name), pk_name))
- return cursor.fetchone()[0]
-
- def no_limit_value(self):
- return None
-
- def quote_name(self, name):
- if name.startswith('"') and name.endswith('"'):
- return name # Quoting once is enough.
- return '"%s"' % name
-
- def set_time_zone_sql(self):
- return "SET TIME ZONE %s"
-
- def sql_flush(self, style, tables, sequences, allow_cascade=False):
- if tables:
- # Perform a single SQL 'TRUNCATE x, y, z...;' statement. It allows
- # us to truncate tables referenced by a foreign key in any other
- # table.
- tables_sql = ', '.join(
- style.SQL_FIELD(self.quote_name(table)) for table in tables)
- if allow_cascade:
- sql = ['%s %s %s;' % (
- style.SQL_KEYWORD('TRUNCATE'),
- tables_sql,
- style.SQL_KEYWORD('CASCADE'),
- )]
- else:
- sql = ['%s %s;' % (
- style.SQL_KEYWORD('TRUNCATE'),
- tables_sql,
- )]
- sql.extend(self.sequence_reset_by_name_sql(style, sequences))
- return sql
- else:
- return []
-
- def sequence_reset_by_name_sql(self, style, sequences):
- # 'ALTER SEQUENCE sequence_name RESTART WITH 1;'... style SQL statements
- # to reset sequence indices
- sql = []
- for sequence_info in sequences:
- table_name = sequence_info['table']
- column_name = sequence_info['column']
- if not (column_name and len(column_name) > 0):
- # This will be the case if it's an m2m using an autogenerated
- # intermediate table (see BaseDatabaseIntrospection.sequence_list)
- column_name = 'id'
- sql.append("%s setval(pg_get_serial_sequence('%s','%s'), 1, false);" % \
- (style.SQL_KEYWORD('SELECT'),
- style.SQL_TABLE(self.quote_name(table_name)),
- style.SQL_FIELD(column_name))
- )
- return sql
-
- def tablespace_sql(self, tablespace, inline=False):
- if inline:
- return "USING INDEX TABLESPACE %s" % self.quote_name(tablespace)
- else:
- return "TABLESPACE %s" % self.quote_name(tablespace)
-
- def sequence_reset_sql(self, style, model_list):
- from django.db import models
- output = []
- qn = self.quote_name
- for model in model_list:
- # Use `coalesce` to set the sequence for each model to the max pk value if there are records,
- # or 1 if there are none. Set the `is_called` property (the third argument to `setval`) to true
- # if there are records (as the max pk value is already in use), otherwise set it to false.
- # Use pg_get_serial_sequence to get the underlying sequence name from the table name
- # and column name (available since PostgreSQL 8)
-
- for f in model._meta.local_fields:
- if isinstance(f, models.AutoField):
- output.append("%s setval(pg_get_serial_sequence('%s','%s'), coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
- (style.SQL_KEYWORD('SELECT'),
- style.SQL_TABLE(qn(model._meta.db_table)),
- style.SQL_FIELD(f.column),
- style.SQL_FIELD(qn(f.column)),
- style.SQL_FIELD(qn(f.column)),
- style.SQL_KEYWORD('IS NOT'),
- style.SQL_KEYWORD('FROM'),
- style.SQL_TABLE(qn(model._meta.db_table))))
- break # Only one AutoField is allowed per model, so don't bother continuing.
- for f in model._meta.many_to_many:
- if not f.rel.through:
- output.append("%s setval(pg_get_serial_sequence('%s','%s'), coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \
- (style.SQL_KEYWORD('SELECT'),
- style.SQL_TABLE(qn(f.m2m_db_table())),
- style.SQL_FIELD('id'),
- style.SQL_FIELD(qn('id')),
- style.SQL_FIELD(qn('id')),
- style.SQL_KEYWORD('IS NOT'),
- style.SQL_KEYWORD('FROM'),
- style.SQL_TABLE(qn(f.m2m_db_table()))))
- return output
-
- def prep_for_iexact_query(self, x):
- return x
-
- def max_name_length(self):
- """
- Returns the maximum length of an identifier.
-
- Note that the maximum length of an identifier is 63 by default, but can
- be changed by recompiling PostgreSQL after editing the NAMEDATALEN
- macro in src/include/pg_config_manual.h .
-
- This implementation simply returns 63, but can easily be overridden by a
- custom database backend that inherits most of its behavior from this one.
- """
-
- return 63
-
- def distinct_sql(self, fields):
- if fields:
- return 'DISTINCT ON (%s)' % ', '.join(fields)
- else:
- return 'DISTINCT'
-
- def last_executed_query(self, cursor, sql, params):
- # http://initd.org/psycopg/docs/cursor.html#cursor.query
- # The query attribute is a Psycopg extension to the DB API 2.0.
- if cursor.query is not None:
- return cursor.query.decode('utf-8')
- return None
-
- def return_insert_id(self):
- return "RETURNING %s", ()
-
- def bulk_insert_sql(self, fields, num_values):
- items_sql = "(%s)" % ", ".join(["%s"] * len(fields))
- return "VALUES " + ", ".join([items_sql] * num_values)
diff --git a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/version.py b/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/version.py
deleted file mode 100644
index 8ef5167..0000000
--- a/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/version.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""
-Extracts the version of the PostgreSQL server.
-"""
-
-import re
-
-# This reg-exp is intentionally fairly flexible here.
-# Needs to be able to handle stuff like:
-# PostgreSQL 8.3.6
-# EnterpriseDB 8.3
-# PostgreSQL 8.3 beta4
-# PostgreSQL 8.4beta1
-VERSION_RE = re.compile(r'\S+ (\d+)\.(\d+)\.?(\d+)?')
-
-
-def _parse_version(text):
- "Internal parsing method. Factored out for testing purposes."
- major, major2, minor = VERSION_RE.search(text).groups()
- try:
- return int(major) * 10000 + int(major2) * 100 + int(minor)
- except (ValueError, TypeError):
- return int(major) * 10000 + int(major2) * 100
-
-def get_version(connection):
- """
- Returns an integer representing the major, minor and revision number of the
- server. Format is the one used for the return value of libpq
- PQServerVersion()/``server_version`` connection attribute (available in
- newer psycopg2 versions.)
-
- For example, 80304 for 8.3.4. The last two digits will be 00 in the case of
- releases (e.g., 80400 for 'PostgreSQL 8.4') or in the case of beta and
- prereleases (e.g. 90100 for 'PostgreSQL 9.1beta2').
-
- PQServerVersion()/``server_version`` doesn't execute a query so try that
- first, then fallback to a ``SELECT version()`` query.
- """
- if hasattr(connection, 'server_version'):
- return connection.server_version
- else:
- cursor = connection.cursor()
- cursor.execute("SELECT version()")
- return _parse_version(cursor.fetchone()[0])
diff --git a/lib/python2.7/site-packages/django/db/backends/signals.py b/lib/python2.7/site-packages/django/db/backends/signals.py
deleted file mode 100644
index c16a63f..0000000
--- a/lib/python2.7/site-packages/django/db/backends/signals.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.dispatch import Signal
-
-connection_created = Signal(providing_args=["connection"])
diff --git a/lib/python2.7/site-packages/django/db/backends/sqlite3/__init__.py b/lib/python2.7/site-packages/django/db/backends/sqlite3/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/lib/python2.7/site-packages/django/db/backends/sqlite3/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py b/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py
deleted file mode 100644
index a219178..0000000
--- a/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py
+++ /dev/null
@@ -1,533 +0,0 @@
-"""
-SQLite3 backend for django.
-
-Works with either the pysqlite2 module or the sqlite3 module in the
-standard library.
-"""
-from __future__ import unicode_literals
-
-import datetime
-import decimal
-import warnings
-import re
-
-from django.db import utils
-from django.db.backends import *
-from django.db.backends.sqlite3.client import DatabaseClient
-from django.db.backends.sqlite3.creation import DatabaseCreation
-from django.db.backends.sqlite3.introspection import DatabaseIntrospection
-from django.db.models import fields
-from django.db.models.sql import aggregates
-from django.utils.dateparse import parse_date, parse_datetime, parse_time
-from django.utils.encoding import force_text
-from django.utils.functional import cached_property
-from django.utils.safestring import SafeBytes
-from django.utils import six
-from django.utils import timezone
-
-try:
- try:
- from pysqlite2 import dbapi2 as Database
- except ImportError:
- from sqlite3 import dbapi2 as Database
-except ImportError as exc:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("Error loading either pysqlite2 or sqlite3 modules (tried in that order): %s" % exc)
-
-try:
- import pytz
-except ImportError:
- pytz = None
-
-DatabaseError = Database.DatabaseError
-IntegrityError = Database.IntegrityError
-
-def parse_datetime_with_timezone_support(value):
- dt = parse_datetime(value)
- # Confirm that dt is naive before overwriting its tzinfo.
- if dt is not None and settings.USE_TZ and timezone.is_naive(dt):
- dt = dt.replace(tzinfo=timezone.utc)
- return dt
-
-def adapt_datetime_with_timezone_support(value):
- # Equivalent to DateTimeField.get_db_prep_value. Used only by raw SQL.
- if settings.USE_TZ:
- if timezone.is_naive(value):
- warnings.warn("SQLite received a naive datetime (%s)"
- " while time zone support is active." % value,
- RuntimeWarning)
- default_timezone = timezone.get_default_timezone()
- value = timezone.make_aware(value, default_timezone)
- value = value.astimezone(timezone.utc).replace(tzinfo=None)
- return value.isoformat(str(" "))
-
-def decoder(conv_func):
- """ The Python sqlite3 interface returns always byte strings.
- This function converts the received value to a regular string before
- passing it to the receiver function.
- """
- return lambda s: conv_func(s.decode('utf-8'))
-
-Database.register_converter(str("bool"), decoder(lambda s: s == '1'))
-Database.register_converter(str("time"), decoder(parse_time))
-Database.register_converter(str("date"), decoder(parse_date))
-Database.register_converter(str("datetime"), decoder(parse_datetime_with_timezone_support))
-Database.register_converter(str("timestamp"), decoder(parse_datetime_with_timezone_support))
-Database.register_converter(str("TIMESTAMP"), decoder(parse_datetime_with_timezone_support))
-Database.register_converter(str("decimal"), decoder(util.typecast_decimal))
-
-Database.register_adapter(datetime.datetime, adapt_datetime_with_timezone_support)
-Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
-if six.PY2 and Database.version_info >= (2, 4, 1):
- # Starting in 2.4.1, the str type is not accepted anymore, therefore,
- # we convert all str objects to Unicode
- # As registering a adapter for a primitive type causes a small
- # slow-down, this adapter is only registered for sqlite3 versions
- # needing it (Python 2.6 and up).
- Database.register_adapter(str, lambda s: s.decode('utf-8'))
- Database.register_adapter(SafeBytes, lambda s: s.decode('utf-8'))
-
-class DatabaseFeatures(BaseDatabaseFeatures):
- # SQLite cannot handle us only partially reading from a cursor's result set
- # and then writing the same rows to the database in another cursor. This
- # setting ensures we always read result sets fully into memory all in one
- # go.
- can_use_chunked_reads = False
- test_db_allows_multiple_connections = False
- supports_unspecified_pk = True
- supports_timezones = False
- supports_1000_query_parameters = False
- supports_mixed_date_datetime_comparisons = False
- has_bulk_insert = True
- can_combine_inserts_with_and_without_auto_increment_pk = False
- autocommits_when_autocommit_is_off = True
- atomic_transactions = False
- supports_paramstyle_pyformat = False
-
- @cached_property
- def uses_savepoints(self):
- return Database.sqlite_version_info >= (3, 6, 8)
-
- @cached_property
- def supports_stddev(self):
- """Confirm support for STDDEV and related stats functions
-
- SQLite supports STDDEV as an extension package; so
- connection.ops.check_aggregate_support() can't unilaterally
- rule out support for STDDEV. We need to manually check
- whether the call works.
- """
- cursor = self.connection.cursor()
- cursor.execute('CREATE TABLE STDDEV_TEST (X INT)')
- try:
- cursor.execute('SELECT STDDEV(*) FROM STDDEV_TEST')
- has_support = True
- except utils.DatabaseError:
- has_support = False
- cursor.execute('DROP TABLE STDDEV_TEST')
- return has_support
-
- @cached_property
- def has_zoneinfo_database(self):
- return pytz is not None
-
-class DatabaseOperations(BaseDatabaseOperations):
- def bulk_batch_size(self, fields, objs):
- """
- SQLite has a compile-time default (SQLITE_LIMIT_VARIABLE_NUMBER) of
- 999 variables per query.
-
- If there is just single field to insert, then we can hit another
- limit, SQLITE_MAX_COMPOUND_SELECT which defaults to 500.
- """
- limit = 999 if len(fields) > 1 else 500
- return (limit // len(fields)) if len(fields) > 0 else len(objs)
-
- def check_aggregate_support(self, aggregate):
- bad_fields = (fields.DateField, fields.DateTimeField, fields.TimeField)
- bad_aggregates = (aggregates.Sum, aggregates.Avg,
- aggregates.Variance, aggregates.StdDev)
- if (isinstance(aggregate.source, bad_fields) and
- isinstance(aggregate, bad_aggregates)):
- raise NotImplementedError(
- 'You cannot use Sum, Avg, StdDev and Variance aggregations '
- 'on date/time fields in sqlite3 '
- 'since date/time is saved as text.')
-
- def date_extract_sql(self, lookup_type, field_name):
- # sqlite doesn't support extract, so we fake it with the user-defined
- # function django_date_extract that's registered in connect(). Note that
- # single quotes are used because this is a string (and could otherwise
- # cause a collision with a field name).
- return "django_date_extract('%s', %s)" % (lookup_type.lower(), field_name)
-
- def date_interval_sql(self, sql, connector, timedelta):
- # It would be more straightforward if we could use the sqlite strftime
- # function, but it does not allow for keeping six digits of fractional
- # second information, nor does it allow for formatting date and datetime
- # values differently. So instead we register our own function that
- # formats the datetime combined with the delta in a manner suitable
- # for comparisons.
- return 'django_format_dtdelta(%s, "%s", "%d", "%d", "%d")' % (sql,
- connector, timedelta.days, timedelta.seconds, timedelta.microseconds)
-
- def date_trunc_sql(self, lookup_type, field_name):
- # sqlite doesn't support DATE_TRUNC, so we fake it with a user-defined
- # function django_date_trunc that's registered in connect(). Note that
- # single quotes are used because this is a string (and could otherwise
- # cause a collision with a field name).
- return "django_date_trunc('%s', %s)" % (lookup_type.lower(), field_name)
-
- def datetime_extract_sql(self, lookup_type, field_name, tzname):
- # Same comment as in date_extract_sql.
- if settings.USE_TZ:
- if pytz is None:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("This query requires pytz, "
- "but it isn't installed.")
- return "django_datetime_extract('%s', %s, %%s)" % (
- lookup_type.lower(), field_name), [tzname]
-
- def datetime_trunc_sql(self, lookup_type, field_name, tzname):
- # Same comment as in date_trunc_sql.
- if settings.USE_TZ:
- if pytz is None:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured("This query requires pytz, "
- "but it isn't installed.")
- return "django_datetime_trunc('%s', %s, %%s)" % (
- lookup_type.lower(), field_name), [tzname]
-
- def drop_foreignkey_sql(self):
- return ""
-
- def pk_default_value(self):
- return "NULL"
-
- def quote_name(self, name):
- if name.startswith('"') and name.endswith('"'):
- return name # Quoting once is enough.
- return '"%s"' % name
-
- def no_limit_value(self):
- return -1
-
- def sql_flush(self, style, tables, sequences, allow_cascade=False):
- # NB: The generated SQL below is specific to SQLite
- # Note: The DELETE FROM... SQL generated below works for SQLite databases
- # because constraints don't exist
- sql = ['%s %s %s;' % (
- style.SQL_KEYWORD('DELETE'),
- style.SQL_KEYWORD('FROM'),
- style.SQL_FIELD(self.quote_name(table))
- ) for table in tables]
- # Note: No requirement for reset of auto-incremented indices (cf. other
- # sql_flush() implementations). Just return SQL at this point
- return sql
-
- def value_to_db_datetime(self, value):
- if value is None:
- return None
-
- # SQLite doesn't support tz-aware datetimes
- if timezone.is_aware(value):
- if settings.USE_TZ:
- value = value.astimezone(timezone.utc).replace(tzinfo=None)
- else:
- raise ValueError("SQLite backend does not support timezone-aware datetimes when USE_TZ is False.")
-
- return six.text_type(value)
-
- def value_to_db_time(self, value):
- if value is None:
- return None
-
- # SQLite doesn't support tz-aware datetimes
- if timezone.is_aware(value):
- raise ValueError("SQLite backend does not support timezone-aware times.")
-
- return six.text_type(value)
-
- def convert_values(self, value, field):
- """SQLite returns floats when it should be returning decimals,
- and gets dates and datetimes wrong.
- For consistency with other backends, coerce when required.
- """
- if value is None:
- return None
-
- internal_type = field.get_internal_type()
- if internal_type == 'DecimalField':
- return util.typecast_decimal(field.format_number(value))
- elif internal_type and internal_type.endswith('IntegerField') or internal_type == 'AutoField':
- return int(value)
- elif internal_type == 'DateField':
- return parse_date(value)
- elif internal_type == 'DateTimeField':
- return parse_datetime_with_timezone_support(value)
- elif internal_type == 'TimeField':
- return parse_time(value)
-
- # No field, or the field isn't known to be a decimal or integer
- return value
-
- def bulk_insert_sql(self, fields, num_values):
- res = []
- res.append("SELECT %s" % ", ".join(
- "%%s AS %s" % self.quote_name(f.column) for f in fields
- ))
- res.extend(["UNION ALL SELECT %s" % ", ".join(["%s"] * len(fields))] * (num_values - 1))
- return " ".join(res)
-
-class DatabaseWrapper(BaseDatabaseWrapper):
- vendor = 'sqlite'
- # SQLite requires LIKE statements to include an ESCAPE clause if the value
- # being escaped has a percent or underscore in it.
- # See http://www.sqlite.org/lang_expr.html for an explanation.
- operators = {
- 'exact': '= %s',
- 'iexact': "LIKE %s ESCAPE '\\'",
- 'contains': "LIKE %s ESCAPE '\\'",
- 'icontains': "LIKE %s ESCAPE '\\'",
- 'regex': 'REGEXP %s',
- 'iregex': "REGEXP '(?i)' || %s",
- 'gt': '> %s',
- 'gte': '>= %s',
- 'lt': '< %s',
- 'lte': '<= %s',
- 'startswith': "LIKE %s ESCAPE '\\'",
- 'endswith': "LIKE %s ESCAPE '\\'",
- 'istartswith': "LIKE %s ESCAPE '\\'",
- 'iendswith': "LIKE %s ESCAPE '\\'",
- }
-
- Database = Database
-
- def __init__(self, *args, **kwargs):
- super(DatabaseWrapper, self).__init__(*args, **kwargs)
-
- self.features = DatabaseFeatures(self)
- self.ops = DatabaseOperations(self)
- self.client = DatabaseClient(self)
- self.creation = DatabaseCreation(self)
- self.introspection = DatabaseIntrospection(self)
- self.validation = BaseDatabaseValidation(self)
-
- def get_connection_params(self):
- settings_dict = self.settings_dict
- if not settings_dict['NAME']:
- from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured(
- "settings.DATABASES is improperly configured. "
- "Please supply the NAME value.")
- kwargs = {
- 'database': settings_dict['NAME'],
- 'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES,
- }
- kwargs.update(settings_dict['OPTIONS'])
- # Always allow the underlying SQLite connection to be shareable
- # between multiple threads. The safe-guarding will be handled at a
- # higher level by the `BaseDatabaseWrapper.allow_thread_sharing`
- # property. This is necessary as the shareability is disabled by
- # default in pysqlite and it cannot be changed once a connection is
- # opened.
- if 'check_same_thread' in kwargs and kwargs['check_same_thread']:
- warnings.warn(
- 'The `check_same_thread` option was provided and set to '
- 'True. It will be overriden with False. Use the '
- '`DatabaseWrapper.allow_thread_sharing` property instead '
- 'for controlling thread shareability.',
- RuntimeWarning
- )
- kwargs.update({'check_same_thread': False})
- return kwargs
-
- def get_new_connection(self, conn_params):
- conn = Database.connect(**conn_params)
- conn.create_function("django_date_extract", 2, _sqlite_date_extract)
- conn.create_function("django_date_trunc", 2, _sqlite_date_trunc)
- conn.create_function("django_datetime_extract", 3, _sqlite_datetime_extract)
- conn.create_function("django_datetime_trunc", 3, _sqlite_datetime_trunc)
- conn.create_function("regexp", 2, _sqlite_regexp)
- conn.create_function("django_format_dtdelta", 5, _sqlite_format_dtdelta)
- return conn
-
- def init_connection_state(self):
- pass
-
- def create_cursor(self):
- return self.connection.cursor(factory=SQLiteCursorWrapper)
-
- def close(self):
- self.validate_thread_sharing()
- # If database is in memory, closing the connection destroys the
- # database. To prevent accidental data loss, ignore close requests on
- # an in-memory db.
- if self.settings_dict['NAME'] != ":memory:":
- BaseDatabaseWrapper.close(self)
-
- def _savepoint_allowed(self):
- # Two conditions are required here:
- # - A sufficiently recent version of SQLite to support savepoints,
- # - Being in a transaction, which can only happen inside 'atomic'.
-
- # When 'isolation_level' is not None, sqlite3 commits before each
- # savepoint; it's a bug. When it is None, savepoints don't make sense
- # because autocommit is enabled. The only exception is inside 'atomic'
- # blocks. To work around that bug, on SQLite, 'atomic' starts a
- # transaction explicitly rather than simply disable autocommit.
- return self.features.uses_savepoints and self.in_atomic_block
-
- def _set_autocommit(self, autocommit):
- if autocommit:
- level = None
- else:
- # sqlite3's internal default is ''. It's different from None.
- # See Modules/_sqlite/connection.c.
- level = ''
- # 'isolation_level' is a misleading API.
- # SQLite always runs at the SERIALIZABLE isolation level.
- with self.wrap_database_errors:
- self.connection.isolation_level = level
-
- def check_constraints(self, table_names=None):
- """
- Checks each table name in `table_names` for rows with invalid foreign key references. This method is
- intended to be used in conjunction with `disable_constraint_checking()` and `enable_constraint_checking()`, to
- determine if rows with invalid references were entered while constraint checks were off.
-
- Raises an IntegrityError on the first invalid foreign key reference encountered (if any) and provides
- detailed information about the invalid reference in the error message.
-
- Backends can override this method if they can more directly apply constraint checking (e.g. via "SET CONSTRAINTS
- ALL IMMEDIATE")
- """
- cursor = self.cursor()
- if table_names is None:
- table_names = self.introspection.table_names(cursor)
- for table_name in table_names:
- primary_key_column_name = self.introspection.get_primary_key_column(cursor, table_name)
- if not primary_key_column_name:
- continue
- key_columns = self.introspection.get_key_columns(cursor, table_name)
- for column_name, referenced_table_name, referenced_column_name in key_columns:
- cursor.execute("""
- SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
- LEFT JOIN `%s` as REFERRED
- ON (REFERRING.`%s` = REFERRED.`%s`)
- WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL"""
- % (primary_key_column_name, column_name, table_name, referenced_table_name,
- column_name, referenced_column_name, column_name, referenced_column_name))
- for bad_row in cursor.fetchall():
- raise utils.IntegrityError("The row in table '%s' with primary key '%s' has an invalid "
- "foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s."
- % (table_name, bad_row[0], table_name, column_name, bad_row[1],
- referenced_table_name, referenced_column_name))
-
- def is_usable(self):
- return True
-
- def _start_transaction_under_autocommit(self):
- """
- Start a transaction explicitly in autocommit mode.
-
- Staying in autocommit mode works around a bug of sqlite3 that breaks
- savepoints when autocommit is disabled.
- """
- self.cursor().execute("BEGIN")
-
-FORMAT_QMARK_REGEX = re.compile(r'(?<!%)%s')
-
-class SQLiteCursorWrapper(Database.Cursor):
- """
- Django uses "format" style placeholders, but pysqlite2 uses "qmark" style.
- This fixes it -- but note that if you want to use a literal "%s" in a query,
- you'll need to use "%%s".
- """
- def execute(self, query, params=None):
- if params is None:
- return Database.Cursor.execute(self, query)
- query = self.convert_query(query)
- return Database.Cursor.execute(self, query, params)
-
- def executemany(self, query, param_list):
- query = self.convert_query(query)
- return Database.Cursor.executemany(self, query, param_list)
-
- def convert_query(self, query):
- return FORMAT_QMARK_REGEX.sub('?', query).replace('%%', '%')
-
-def _sqlite_date_extract(lookup_type, dt):
- if dt is None:
- return None
- try:
- dt = util.typecast_timestamp(dt)
- except (ValueError, TypeError):
- return None
- if lookup_type == 'week_day':
- return (dt.isoweekday() % 7) + 1
- else:
- return getattr(dt, lookup_type)
-
-def _sqlite_date_trunc(lookup_type, dt):
- try:
- dt = util.typecast_timestamp(dt)
- except (ValueError, TypeError):
- return None
- if lookup_type == 'year':
- return "%i-01-01" % dt.year
- elif lookup_type == 'month':
- return "%i-%02i-01" % (dt.year, dt.month)
- elif lookup_type == 'day':
- return "%i-%02i-%02i" % (dt.year, dt.month, dt.day)
-
-def _sqlite_datetime_extract(lookup_type, dt, tzname):
- if dt is None:
- return None
- try:
- dt = util.typecast_timestamp(dt)
- except (ValueError, TypeError):
- return None
- if tzname is not None:
- dt = timezone.localtime(dt, pytz.timezone(tzname))
- if lookup_type == 'week_day':
- return (dt.isoweekday() % 7) + 1
- else:
- return getattr(dt, lookup_type)
-
-def _sqlite_datetime_trunc(lookup_type, dt, tzname):
- try:
- dt = util.typecast_timestamp(dt)
- except (ValueError, TypeError):
- return None
- if tzname is not None:
- dt = timezone.localtime(dt, pytz.timezone(tzname))
- if lookup_type == 'year':
- return "%i-01-01 00:00:00" % dt.year
- elif lookup_type == 'month':
- return "%i-%02i-01 00:00:00" % (dt.year, dt.month)
- elif lookup_type == 'day':
- return "%i-%02i-%02i 00:00:00" % (dt.year, dt.month, dt.day)
- elif lookup_type == 'hour':
- return "%i-%02i-%02i %02i:00:00" % (dt.year, dt.month, dt.day, dt.hour)
- elif lookup_type == 'minute':
- return "%i-%02i-%02i %02i:%02i:00" % (dt.year, dt.month, dt.day, dt.hour, dt.minute)
- elif lookup_type == 'second':
- return "%i-%02i-%02i %02i:%02i:%02i" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
-
-def _sqlite_format_dtdelta(dt, conn, days, secs, usecs):
- try:
- dt = util.typecast_timestamp(dt)
- delta = datetime.timedelta(int(days), int(secs), int(usecs))
- if conn.strip() == '+':
- dt = dt + delta
- else:
- dt = dt - delta
- except (ValueError, TypeError):
- return None
- # typecast_timestamp returns a date or a datetime without timezone.
- # It will be formatted as "%Y-%m-%d" or "%Y-%m-%d %H:%M:%S[.%f]"
- return str(dt)
-
-def _sqlite_regexp(re_pattern, re_string):
- return bool(re.search(re_pattern, force_text(re_string))) if re_string is not None else False
diff --git a/lib/python2.7/site-packages/django/db/backends/sqlite3/client.py b/lib/python2.7/site-packages/django/db/backends/sqlite3/client.py
deleted file mode 100644
index 5b5b732..0000000
--- a/lib/python2.7/site-packages/django/db/backends/sqlite3/client.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import os
-import sys
-
-from django.db.backends import BaseDatabaseClient
-
-class DatabaseClient(BaseDatabaseClient):
- executable_name = 'sqlite3'
-
- def runshell(self):
- args = [self.executable_name,
- self.connection.settings_dict['NAME']]
- if os.name == 'nt':
- sys.exit(os.system(" ".join(args)))
- else:
- os.execvp(self.executable_name, args)
-
diff --git a/lib/python2.7/site-packages/django/db/backends/sqlite3/creation.py b/lib/python2.7/site-packages/django/db/backends/sqlite3/creation.py
deleted file mode 100644
index a9fb273..0000000
--- a/lib/python2.7/site-packages/django/db/backends/sqlite3/creation.py
+++ /dev/null
@@ -1,88 +0,0 @@
-import os
-import sys
-from django.db.backends.creation import BaseDatabaseCreation
-from django.utils.six.moves import input
-
-class DatabaseCreation(BaseDatabaseCreation):
- # SQLite doesn't actually support most of these types, but it "does the right
- # thing" given more verbose field definitions, so leave them as is so that
- # schema inspection is more useful.
- data_types = {
- 'AutoField': 'integer',
- 'BinaryField': 'BLOB',
- 'BooleanField': 'bool',
- 'CharField': 'varchar(%(max_length)s)',
- 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
- 'DateField': 'date',
- 'DateTimeField': 'datetime',
- 'DecimalField': 'decimal',
- 'FileField': 'varchar(%(max_length)s)',
- 'FilePathField': 'varchar(%(max_length)s)',
- 'FloatField': 'real',
- 'IntegerField': 'integer',
- 'BigIntegerField': 'bigint',
- 'IPAddressField': 'char(15)',
- 'GenericIPAddressField': 'char(39)',
- 'NullBooleanField': 'bool',
- 'OneToOneField': 'integer',
- 'PositiveIntegerField': 'integer unsigned',
- 'PositiveSmallIntegerField': 'smallint unsigned',
- 'SlugField': 'varchar(%(max_length)s)',
- 'SmallIntegerField': 'smallint',
- 'TextField': 'text',
- 'TimeField': 'time',
- }
-
- def sql_for_pending_references(self, model, style, pending_references):
- "SQLite3 doesn't support constraints"
- return []
-
- def sql_remove_table_constraints(self, model, references_to_delete, style):
- "SQLite3 doesn't support constraints"
- return []
-
- def _get_test_db_name(self):
- test_database_name = self.connection.settings_dict['TEST_NAME']
- if test_database_name and test_database_name != ':memory:':
- return test_database_name
- return ':memory:'
-
- def _create_test_db(self, verbosity, autoclobber):
- test_database_name = self._get_test_db_name()
- if test_database_name != ':memory:':
- # Erase the old test database
- if verbosity >= 1:
- print("Destroying old test database '%s'..." % self.connection.alias)
- if os.access(test_database_name, os.F_OK):
- if not autoclobber:
- confirm = input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % test_database_name)
- if autoclobber or confirm == 'yes':
- try:
- os.remove(test_database_name)
- except Exception as e:
- sys.stderr.write("Got an error deleting the old test database: %s\n" % e)
- sys.exit(2)
- else:
- print("Tests cancelled.")
- sys.exit(1)
- return test_database_name
-
- def _destroy_test_db(self, test_database_name, verbosity):
- if test_database_name and test_database_name != ":memory:":
- # Remove the SQLite database file
- os.remove(test_database_name)
-
- def test_db_signature(self):
- """
- Returns a tuple that uniquely identifies a test database.
-
- This takes into account the special cases of ":memory:" and "" for
- SQLite since the databases will be distinct despite having the same
- TEST_NAME. See http://www.sqlite.org/inmemorydb.html
- """
- settings_dict = self.connection.settings_dict
- test_dbname = self._get_test_db_name()
- sig = [self.connection.settings_dict['NAME']]
- if test_dbname == ':memory:':
- sig.append(self.connection.alias)
- return tuple(sig)
diff --git a/lib/python2.7/site-packages/django/db/backends/sqlite3/introspection.py b/lib/python2.7/site-packages/django/db/backends/sqlite3/introspection.py
deleted file mode 100644
index 431e112..0000000
--- a/lib/python2.7/site-packages/django/db/backends/sqlite3/introspection.py
+++ /dev/null
@@ -1,185 +0,0 @@
-import re
-from django.db.backends import BaseDatabaseIntrospection, FieldInfo
-
-field_size_re = re.compile(r'^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$')
-
-def get_field_size(name):
- """ Extract the size number from a "varchar(11)" type name """
- m = field_size_re.search(name)
- return int(m.group(1)) if m else None
-
-
-# This light wrapper "fakes" a dictionary interface, because some SQLite data
-# types include variables in them -- e.g. "varchar(30)" -- and can't be matched
-# as a simple dictionary lookup.
-class FlexibleFieldLookupDict(object):
- # Maps SQL types to Django Field types. Some of the SQL types have multiple
- # entries here because SQLite allows for anything and doesn't normalize the
- # field type; it uses whatever was given.
- base_data_types_reverse = {
- 'bool': 'BooleanField',
- 'boolean': 'BooleanField',
- 'smallint': 'SmallIntegerField',
- 'smallint unsigned': 'PositiveSmallIntegerField',
- 'smallinteger': 'SmallIntegerField',
- 'int': 'IntegerField',
- 'integer': 'IntegerField',
- 'bigint': 'BigIntegerField',
- 'integer unsigned': 'PositiveIntegerField',
- 'decimal': 'DecimalField',
- 'real': 'FloatField',
- 'text': 'TextField',
- 'char': 'CharField',
- 'blob': 'BinaryField',
- 'date': 'DateField',
- 'datetime': 'DateTimeField',
- 'time': 'TimeField',
- }
-
- def __getitem__(self, key):
- key = key.lower()
- try:
- return self.base_data_types_reverse[key]
- except KeyError:
- size = get_field_size(key)
- if size is not None:
- return ('CharField', {'max_length': size})
- raise KeyError
-
-class DatabaseIntrospection(BaseDatabaseIntrospection):
- data_types_reverse = FlexibleFieldLookupDict()
-
- def get_table_list(self, cursor):
- "Returns a list of table names in the current database."
- # Skip the sqlite_sequence system table used for autoincrement key
- # generation.
- cursor.execute("""
- SELECT name FROM sqlite_master
- WHERE type='table' AND NOT name='sqlite_sequence'
- ORDER BY name""")
- return [row[0] for row in cursor.fetchall()]
-
- def get_table_description(self, cursor, table_name):
- "Returns a description of the table, with the DB-API cursor.description interface."
- return [FieldInfo(info['name'], info['type'], None, info['size'], None, None,
- info['null_ok']) for info in self._table_info(cursor, table_name)]
-
- def get_relations(self, cursor, table_name):
- """
- Returns a dictionary of {field_index: (field_index_other_table, other_table)}
- representing all relationships to the given table. Indexes are 0-based.
- """
-
- # Dictionary of relations to return
- relations = {}
-
- # Schema for this table
- cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s AND type = %s", [table_name, "table"])
- results = cursor.fetchone()[0].strip()
- results = results[results.index('(')+1:results.rindex(')')]
-
- # Walk through and look for references to other tables. SQLite doesn't
- # really have enforced references, but since it echoes out the SQL used
- # to create the table we can look for REFERENCES statements used there.
- for field_index, field_desc in enumerate(results.split(',')):
- field_desc = field_desc.strip()
- if field_desc.startswith("UNIQUE"):
- continue
-
- m = re.search('references (.*) \(["|](.*)["|]\)', field_desc, re.I)
- if not m:
- continue
-
- table, column = [s.strip('"') for s in m.groups()]
-
- cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s", [table])
- result = cursor.fetchall()[0]
- other_table_results = result[0].strip()
- li, ri = other_table_results.index('('), other_table_results.rindex(')')
- other_table_results = other_table_results[li+1:ri]
-
-
- for other_index, other_desc in enumerate(other_table_results.split(',')):
- other_desc = other_desc.strip()
- if other_desc.startswith('UNIQUE'):
- continue
-
- name = other_desc.split(' ', 1)[0].strip('"')
- if name == column:
- relations[field_index] = (other_index, table)
- break
-
- return relations
-
- def get_key_columns(self, cursor, table_name):
- """
- Returns a list of (column_name, referenced_table_name, referenced_column_name) for all
- key columns in given table.
- """
- key_columns = []
-
- # Schema for this table
- cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s AND type = %s", [table_name, "table"])
- results = cursor.fetchone()[0].strip()
- results = results[results.index('(')+1:results.rindex(')')]
-
- # Walk through and look for references to other tables. SQLite doesn't
- # really have enforced references, but since it echoes out the SQL used
- # to create the table we can look for REFERENCES statements used there.
- for field_index, field_desc in enumerate(results.split(',')):
- field_desc = field_desc.strip()
- if field_desc.startswith("UNIQUE"):
- continue
-
- m = re.search('"(.*)".*references (.*) \(["|](.*)["|]\)', field_desc, re.I)
- if not m:
- continue
-
- # This will append (column_name, referenced_table_name, referenced_column_name) to key_columns
- key_columns.append(tuple([s.strip('"') for s in m.groups()]))
-
- return key_columns
-
- def get_indexes(self, cursor, table_name):
- indexes = {}
- for info in self._table_info(cursor, table_name):
- if info['pk'] != 0:
- indexes[info['name']] = {'primary_key': True,
- 'unique': False}
- cursor.execute('PRAGMA index_list(%s)' % self.connection.ops.quote_name(table_name))
- # seq, name, unique
- for index, unique in [(field[1], field[2]) for field in cursor.fetchall()]:
- cursor.execute('PRAGMA index_info(%s)' % self.connection.ops.quote_name(index))
- info = cursor.fetchall()
- # Skip indexes across multiple fields
- if len(info) != 1:
- continue
- name = info[0][2] # seqno, cid, name
- indexes[name] = {'primary_key': False,
- 'unique': unique}
- return indexes
-
- def get_primary_key_column(self, cursor, table_name):
- """
- Get the column name of the primary key for the given table.
- """
- # Don't use PRAGMA because that causes issues with some transactions
- cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s AND type = %s", [table_name, "table"])
- results = cursor.fetchone()[0].strip()
- results = results[results.index('(')+1:results.rindex(')')]
- for field_desc in results.split(','):
- field_desc = field_desc.strip()
- m = re.search('"(.*)".*PRIMARY KEY$', field_desc)
- if m:
- return m.groups()[0]
- return None
-
- def _table_info(self, cursor, name):
- cursor.execute('PRAGMA table_info(%s)' % self.connection.ops.quote_name(name))
- # cid, name, type, notnull, dflt_value, pk
- return [{'name': field[1],
- 'type': field[2],
- 'size': get_field_size(field[2]),
- 'null_ok': not field[3],
- 'pk': field[5] # undocumented
- } for field in cursor.fetchall()]
diff --git a/lib/python2.7/site-packages/django/db/backends/util.py b/lib/python2.7/site-packages/django/db/backends/util.py
deleted file mode 100644
index 2820007..0000000
--- a/lib/python2.7/site-packages/django/db/backends/util.py
+++ /dev/null
@@ -1,179 +0,0 @@
-from __future__ import unicode_literals
-
-import datetime
-import decimal
-import hashlib
-import logging
-from time import time
-
-from django.conf import settings
-from django.utils.encoding import force_bytes
-from django.utils.timezone import utc
-
-
-logger = logging.getLogger('django.db.backends')
-
-
-class CursorWrapper(object):
- def __init__(self, cursor, db):
- self.cursor = cursor
- self.db = db
-
- WRAP_ERROR_ATTRS = frozenset(['fetchone', 'fetchmany', 'fetchall', 'nextset'])
-
- def __getattr__(self, attr):
- cursor_attr = getattr(self.cursor, attr)
- if attr in CursorWrapper.WRAP_ERROR_ATTRS:
- return self.db.wrap_database_errors(cursor_attr)
- else:
- return cursor_attr
-
- def __iter__(self):
- return iter(self.cursor)
-
- # The following methods cannot be implemented in __getattr__, because the
- # code must run when the method is invoked, not just when it is accessed.
-
- def callproc(self, procname, params=None):
- self.db.validate_no_broken_transaction()
- self.db.set_dirty()
- with self.db.wrap_database_errors:
- if params is None:
- return self.cursor.callproc(procname)
- else:
- return self.cursor.callproc(procname, params)
-
- def execute(self, sql, params=None):
- self.db.validate_no_broken_transaction()
- self.db.set_dirty()
- with self.db.wrap_database_errors:
- if params is None:
- return self.cursor.execute(sql)
- else:
- return self.cursor.execute(sql, params)
-
- def executemany(self, sql, param_list):
- self.db.validate_no_broken_transaction()
- self.db.set_dirty()
- with self.db.wrap_database_errors:
- return self.cursor.executemany(sql, param_list)
-
-
-class CursorDebugWrapper(CursorWrapper):
-
- # XXX callproc isn't instrumented at this time.
-
- def execute(self, sql, params=None):
- start = time()
- try:
- return super(CursorDebugWrapper, self).execute(sql, params)
- finally:
- stop = time()
- duration = stop - start
- sql = self.db.ops.last_executed_query(self.cursor, sql, params)
- self.db.queries.append({
- 'sql': sql,
- 'time': "%.3f" % duration,
- })
- logger.debug('(%.3f) %s; args=%s' % (duration, sql, params),
- extra={'duration': duration, 'sql': sql, 'params': params}
- )
-
- def executemany(self, sql, param_list):
- start = time()
- try:
- return super(CursorDebugWrapper, self).executemany(sql, param_list)
- finally:
- stop = time()
- duration = stop - start
- try:
- times = len(param_list)
- except TypeError: # param_list could be an iterator
- times = '?'
- self.db.queries.append({
- 'sql': '%s times: %s' % (times, sql),
- 'time': "%.3f" % duration,
- })
- logger.debug('(%.3f) %s; args=%s' % (duration, sql, param_list),
- extra={'duration': duration, 'sql': sql, 'params': param_list}
- )
-
-
-###############################################
-# Converters from database (string) to Python #
-###############################################
-
-def typecast_date(s):
- return datetime.date(*map(int, s.split('-'))) if s else None # returns None if s is null
-
-def typecast_time(s): # does NOT store time zone information
- if not s: return None
- hour, minutes, seconds = s.split(':')
- if '.' in seconds: # check whether seconds have a fractional part
- seconds, microseconds = seconds.split('.')
- else:
- microseconds = '0'
- return datetime.time(int(hour), int(minutes), int(seconds), int(float('.'+microseconds) * 1000000))
-
-def typecast_timestamp(s): # does NOT store time zone information
- # "2005-07-29 15:48:00.590358-05"
- # "2005-07-29 09:56:00-05"
- if not s: return None
- if not ' ' in s: return typecast_date(s)
- d, t = s.split()
- # Extract timezone information, if it exists. Currently we just throw
- # it away, but in the future we may make use of it.
- if '-' in t:
- t, tz = t.split('-', 1)
- tz = '-' + tz
- elif '+' in t:
- t, tz = t.split('+', 1)
- tz = '+' + tz
- else:
- tz = ''
- dates = d.split('-')
- times = t.split(':')
- seconds = times[2]
- if '.' in seconds: # check whether seconds have a fractional part
- seconds, microseconds = seconds.split('.')
- else:
- microseconds = '0'
- tzinfo = utc if settings.USE_TZ else None
- return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
- int(times[0]), int(times[1]), int(seconds),
- int((microseconds + '000000')[:6]), tzinfo)
-
-def typecast_decimal(s):
- if s is None or s == '':
- return None
- return decimal.Decimal(s)
-
-###############################################
-# Converters from Python to database (string) #
-###############################################
-
-def rev_typecast_decimal(d):
- if d is None:
- return None
- return str(d)
-
-def truncate_name(name, length=None, hash_len=4):
- """Shortens a string to a repeatable mangled version with the given length.
- """
- if length is None or len(name) <= length:
- return name
-
- hsh = hashlib.md5(force_bytes(name)).hexdigest()[:hash_len]
- return '%s%s' % (name[:length-hash_len], hsh)
-
-def format_number(value, max_digits, decimal_places):
- """
- Formats a number into a string with the requisite number of digits and
- decimal places.
- """
- if isinstance(value, decimal.Decimal):
- context = decimal.getcontext().copy()
- context.prec = max_digits
- return "{0:f}".format(value.quantize(decimal.Decimal(".1") ** decimal_places, context=context))
- else:
- return "%.*f" % (decimal_places, value)
diff --git a/lib/python2.7/site-packages/django/db/models/__init__.py b/lib/python2.7/site-packages/django/db/models/__init__.py
deleted file mode 100644
index b5dd1a5..0000000
--- a/lib/python2.7/site-packages/django/db/models/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from functools import wraps
-
-from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
-from django.db.models.loading import get_apps, get_app_paths, get_app, get_models, get_model, register_models, UnavailableApp
-from django.db.models.query import Q
-from django.db.models.expressions import F
-from django.db.models.manager import Manager
-from django.db.models.base import Model
-from django.db.models.aggregates import *
-from django.db.models.fields import *
-from django.db.models.fields.subclassing import SubfieldBase
-from django.db.models.fields.files import FileField, ImageField
-from django.db.models.fields.related import ForeignKey, ForeignObject, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel
-from django.db.models.deletion import CASCADE, PROTECT, SET, SET_NULL, SET_DEFAULT, DO_NOTHING, ProtectedError
-from django.db.models import signals
-
-
-def permalink(func):
- """
- Decorator that calls urlresolvers.reverse() to return a URL using
- parameters returned by the decorated function "func".
-
- "func" should be a function that returns a tuple in one of the
- following formats:
- (viewname, viewargs)
- (viewname, viewargs, viewkwargs)
- """
- from django.core.urlresolvers import reverse
- @wraps(func)
- def inner(*args, **kwargs):
- bits = func(*args, **kwargs)
- return reverse(bits[0], None, *bits[1:3])
- return inner
diff --git a/lib/python2.7/site-packages/django/db/models/aggregates.py b/lib/python2.7/site-packages/django/db/models/aggregates.py
deleted file mode 100644
index b89db1c..0000000
--- a/lib/python2.7/site-packages/django/db/models/aggregates.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-Classes to represent the definitions of aggregate functions.
-"""
-from django.db.models.constants import LOOKUP_SEP
-
-def refs_aggregate(lookup_parts, aggregates):
- """
- A little helper method to check if the lookup_parts contains references
- to the given aggregates set. Because the LOOKUP_SEP is contained in the
- default annotation names we must check each prefix of the lookup_parts
- for match.
- """
- for i in range(len(lookup_parts) + 1):
- if LOOKUP_SEP.join(lookup_parts[0:i]) in aggregates:
- return True
- return False
-
-class Aggregate(object):
- """
- Default Aggregate definition.
- """
- def __init__(self, lookup, **extra):
- """Instantiate a new aggregate.
-
- * lookup is the field on which the aggregate operates.
- * extra is a dictionary of additional data to provide for the
- aggregate definition
-
- Also utilizes the class variables:
- * name, the identifier for this aggregate function.
- """
- self.lookup = lookup
- self.extra = extra
-
- def _default_alias(self):
- return '%s__%s' % (self.lookup, self.name.lower())
- default_alias = property(_default_alias)
-
- def add_to_query(self, query, alias, col, source, is_summary):
- """Add the aggregate to the nominated query.
-
- This method is used to convert the generic Aggregate definition into a
- backend-specific definition.
-
- * query is the backend-specific query instance to which the aggregate
- is to be added.
- * col is a column reference describing the subject field
- of the aggregate. It can be an alias, or a tuple describing
- a table and column name.
- * source is the underlying field or aggregate definition for
- the column reference. If the aggregate is not an ordinal or
- computed type, this reference is used to determine the coerced
- output type of the aggregate.
- * is_summary is a boolean that is set True if the aggregate is a
- summary value rather than an annotation.
- """
- klass = getattr(query.aggregates_module, self.name)
- aggregate = klass(col, source=source, is_summary=is_summary, **self.extra)
- query.aggregates[alias] = aggregate
-
-class Avg(Aggregate):
- name = 'Avg'
-
-class Count(Aggregate):
- name = 'Count'
-
-class Max(Aggregate):
- name = 'Max'
-
-class Min(Aggregate):
- name = 'Min'
-
-class StdDev(Aggregate):
- name = 'StdDev'
-
-class Sum(Aggregate):
- name = 'Sum'
-
-class Variance(Aggregate):
- name = 'Variance'
diff --git a/lib/python2.7/site-packages/django/db/models/base.py b/lib/python2.7/site-packages/django/db/models/base.py
deleted file mode 100644
index f6001b4..0000000
--- a/lib/python2.7/site-packages/django/db/models/base.py
+++ /dev/null
@@ -1,1042 +0,0 @@
-from __future__ import unicode_literals
-
-import copy
-import sys
-from functools import update_wrapper
-from django.utils.six.moves import zip
-
-import django.db.models.manager # Imported to register signal handler.
-from django.conf import settings
-from django.core.exceptions import (ObjectDoesNotExist,
- MultipleObjectsReturned, FieldError, ValidationError, NON_FIELD_ERRORS)
-from django.db.models.fields import AutoField, FieldDoesNotExist
-from django.db.models.fields.related import (ForeignObjectRel, ManyToOneRel,
- OneToOneField, add_lazy_relation)
-from django.db import (router, transaction, DatabaseError,
- DEFAULT_DB_ALIAS)
-from django.db.models.query import Q
-from django.db.models.query_utils import DeferredAttribute, deferred_class_factory
-from django.db.models.deletion import Collector
-from django.db.models.options import Options
-from django.db.models import signals
-from django.db.models.loading import register_models, get_model
-from django.utils.translation import ugettext_lazy as _
-from django.utils.functional import curry
-from django.utils.encoding import force_str, force_text
-from django.utils import six
-from django.utils.text import get_text_list, capfirst
-
-
-def subclass_exception(name, parents, module, attached_to=None):
- """
- Create exception subclass. Used by ModelBase below.
-
- If 'attached_to' is supplied, the exception will be created in a way that
- allows it to be pickled, assuming the returned exception class will be added
- as an attribute to the 'attached_to' class.
- """
- class_dict = {'__module__': module}
- if attached_to is not None:
- def __reduce__(self):
- # Exceptions are special - they've got state that isn't
- # in self.__dict__. We assume it is all in self.args.
- return (unpickle_inner_exception, (attached_to, name), self.args)
-
- def __setstate__(self, args):
- self.args = args
-
- class_dict['__reduce__'] = __reduce__
- class_dict['__setstate__'] = __setstate__
-
- return type(name, parents, class_dict)
-
-
-class ModelBase(type):
- """
- Metaclass for all models.
- """
- def __new__(cls, name, bases, attrs):
- super_new = super(ModelBase, cls).__new__
-
- # six.with_metaclass() inserts an extra class called 'NewBase' in the
- # inheritance tree: Model -> NewBase -> object. But the initialization
- # should be executed only once for a given model class.
-
- # attrs will never be empty for classes declared in the standard way
- # (ie. with the `class` keyword). This is quite robust.
- if name == 'NewBase' and attrs == {}:
- return super_new(cls, name, bases, attrs)
-
- # Also ensure initialization is only performed for subclasses of Model
- # (excluding Model class itself).
- parents = [b for b in bases if isinstance(b, ModelBase) and
- not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))]
- if not parents:
- return super_new(cls, name, bases, attrs)
-
- # Create the class.
- module = attrs.pop('__module__')
- new_class = super_new(cls, name, bases, {'__module__': module})
- attr_meta = attrs.pop('Meta', None)
- abstract = getattr(attr_meta, 'abstract', False)
- if not attr_meta:
- meta = getattr(new_class, 'Meta', None)
- else:
- meta = attr_meta
- base_meta = getattr(new_class, '_meta', None)
-
- if getattr(meta, 'app_label', None) is None:
- # Figure out the app_label by looking one level up.
- # For 'django.contrib.sites.models', this would be 'sites'.
- model_module = sys.modules[new_class.__module__]
- kwargs = {"app_label": model_module.__name__.split('.')[-2]}
- else:
- kwargs = {}
-
- new_class.add_to_class('_meta', Options(meta, **kwargs))
- if not abstract:
- new_class.add_to_class('DoesNotExist', subclass_exception(str('DoesNotExist'),
- tuple(x.DoesNotExist
- for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
- or (ObjectDoesNotExist,),
- module, attached_to=new_class))
- new_class.add_to_class('MultipleObjectsReturned', subclass_exception(str('MultipleObjectsReturned'),
- tuple(x.MultipleObjectsReturned
- for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
- or (MultipleObjectsReturned,),
- module, attached_to=new_class))
- if base_meta and not base_meta.abstract:
- # Non-abstract child classes inherit some attributes from their
- # non-abstract parent (unless an ABC comes before it in the
- # method resolution order).
- if not hasattr(meta, 'ordering'):
- new_class._meta.ordering = base_meta.ordering
- if not hasattr(meta, 'get_latest_by'):
- new_class._meta.get_latest_by = base_meta.get_latest_by
-
- is_proxy = new_class._meta.proxy
-
- # If the model is a proxy, ensure that the base class
- # hasn't been swapped out.
- if is_proxy and base_meta and base_meta.swapped:
- raise TypeError("%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped))
-
- if getattr(new_class, '_default_manager', None):
- if not is_proxy:
- # Multi-table inheritance doesn't inherit default manager from
- # parents.
- new_class._default_manager = None
- new_class._base_manager = None
- else:
- # Proxy classes do inherit parent's default manager, if none is
- # set explicitly.
- new_class._default_manager = new_class._default_manager._copy_to_model(new_class)
- new_class._base_manager = new_class._base_manager._copy_to_model(new_class)
-
- # Bail out early if we have already created this class.
- m = get_model(new_class._meta.app_label, name,
- seed_cache=False, only_installed=False)
- if m is not None:
- return m
-
- # Add all attributes to the class.
- for obj_name, obj in attrs.items():
- new_class.add_to_class(obj_name, obj)
-
- # All the fields of any type declared on this model
- new_fields = new_class._meta.local_fields + \
- new_class._meta.local_many_to_many + \
- new_class._meta.virtual_fields
- field_names = set([f.name for f in new_fields])
-
- # Basic setup for proxy models.
- if is_proxy:
- base = None
- for parent in [cls for cls in parents if hasattr(cls, '_meta')]:
- if parent._meta.abstract:
- if parent._meta.fields:
- raise TypeError("Abstract base class containing model fields not permitted for proxy model '%s'." % name)
- else:
- continue
- if base is not None:
- raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name)
- else:
- base = parent
- if base is None:
- raise TypeError("Proxy model '%s' has no non-abstract model base class." % name)
- if (new_class._meta.local_fields or
- new_class._meta.local_many_to_many):
- raise FieldError("Proxy model '%s' contains model fields." % name)
- new_class._meta.setup_proxy(base)
- new_class._meta.concrete_model = base._meta.concrete_model
- else:
- new_class._meta.concrete_model = new_class
-
- # Do the appropriate setup for any model parents.
- o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields
- if isinstance(f, OneToOneField)])
-
- for base in parents:
- original_base = base
- if not hasattr(base, '_meta'):
- # Things without _meta aren't functional models, so they're
- # uninteresting parents.
- continue
-
- parent_fields = base._meta.local_fields + base._meta.local_many_to_many
- # Check for clashes between locally declared fields and those
- # on the base classes (we cannot handle shadowed fields at the
- # moment).
- for field in parent_fields:
- if field.name in field_names:
- raise FieldError('Local field %r in class %r clashes '
- 'with field of similar name from '
- 'base class %r' %
- (field.name, name, base.__name__))
- if not base._meta.abstract:
- # Concrete classes...
- base = base._meta.concrete_model
- if base in o2o_map:
- field = o2o_map[base]
- elif not is_proxy:
- attr_name = '%s_ptr' % base._meta.model_name
- field = OneToOneField(base, name=attr_name,
- auto_created=True, parent_link=True)
- new_class.add_to_class(attr_name, field)
- else:
- field = None
- new_class._meta.parents[base] = field
- else:
- # .. and abstract ones.
- for field in parent_fields:
- new_class.add_to_class(field.name, copy.deepcopy(field))
-
- # Pass any non-abstract parent classes onto child.
- new_class._meta.parents.update(base._meta.parents)
-
- # Inherit managers from the abstract base classes.
- new_class.copy_managers(base._meta.abstract_managers)
-
- # Proxy models inherit the non-abstract managers from their base,
- # unless they have redefined any of them.
- if is_proxy:
- new_class.copy_managers(original_base._meta.concrete_managers)
-
- # Inherit virtual fields (like GenericForeignKey) from the parent
- # class
- for field in base._meta.virtual_fields:
- if base._meta.abstract and field.name in field_names:
- raise FieldError('Local field %r in class %r clashes '\
- 'with field of similar name from '\
- 'abstract base class %r' % \
- (field.name, name, base.__name__))
- new_class.add_to_class(field.name, copy.deepcopy(field))
-
- if abstract:
- # Abstract base models can't be instantiated and don't appear in
- # the list of models for an app. We do the final setup for them a
- # little differently from normal models.
- attr_meta.abstract = False
- new_class.Meta = attr_meta
- return new_class
-
- new_class._prepare()
- register_models(new_class._meta.app_label, new_class)
-
- # Because of the way imports happen (recursively), we may or may not be
- # the first time this model tries to register with the framework. There
- # should only be one class for each model, so we always return the
- # registered version.
- return get_model(new_class._meta.app_label, name,
- seed_cache=False, only_installed=False)
-
- def copy_managers(cls, base_managers):
- # This is in-place sorting of an Options attribute, but that's fine.
- base_managers.sort()
- for _, mgr_name, manager in base_managers:
- val = getattr(cls, mgr_name, None)
- if not val or val is manager:
- new_manager = manager._copy_to_model(cls)
- cls.add_to_class(mgr_name, new_manager)
-
- def add_to_class(cls, name, value):
- if hasattr(value, 'contribute_to_class'):
- value.contribute_to_class(cls, name)
- else:
- setattr(cls, name, value)
-
- def _prepare(cls):
- """
- Creates some methods once self._meta has been populated.
- """
- opts = cls._meta
- opts._prepare(cls)
-
- if opts.order_with_respect_to:
- cls.get_next_in_order = curry(cls._get_next_or_previous_in_order, is_next=True)
- cls.get_previous_in_order = curry(cls._get_next_or_previous_in_order, is_next=False)
-
- # defer creating accessors on the foreign class until we are
- # certain it has been created
- def make_foreign_order_accessors(field, model, cls):
- setattr(
- field.rel.to,
- 'get_%s_order' % cls.__name__.lower(),
- curry(method_get_order, cls)
- )
- setattr(
- field.rel.to,
- 'set_%s_order' % cls.__name__.lower(),
- curry(method_set_order, cls)
- )
- add_lazy_relation(
- cls,
- opts.order_with_respect_to,
- opts.order_with_respect_to.rel.to,
- make_foreign_order_accessors
- )
-
- # Give the class a docstring -- its definition.
- if cls.__doc__ is None:
- cls.__doc__ = "%s(%s)" % (cls.__name__, ", ".join([f.attname for f in opts.fields]))
-
- if hasattr(cls, 'get_absolute_url'):
- cls.get_absolute_url = update_wrapper(curry(get_absolute_url, opts, cls.get_absolute_url),
- cls.get_absolute_url)
-
- signals.class_prepared.send(sender=cls)
-
-
-class ModelState(object):
- """
- A class for storing instance state
- """
- def __init__(self, db=None):
- self.db = db
- # If true, uniqueness validation checks will consider this a new, as-yet-unsaved object.
- # Necessary for correct validation of new instances of objects with explicit (non-auto) PKs.
- # This impacts validation only; it has no effect on the actual save.
- self.adding = True
-
-
-class Model(six.with_metaclass(ModelBase)):
- _deferred = False
-
- def __init__(self, *args, **kwargs):
- signals.pre_init.send(sender=self.__class__, args=args, kwargs=kwargs)
-
- # Set up the storage for instance state
- self._state = ModelState()
-
- # There is a rather weird disparity here; if kwargs, it's set, then args
- # overrides it. It should be one or the other; don't duplicate the work
- # The reason for the kwargs check is that standard iterator passes in by
- # args, and instantiation for iteration is 33% faster.
- args_len = len(args)
- if args_len > len(self._meta.concrete_fields):
- # Daft, but matches old exception sans the err msg.
- raise IndexError("Number of args exceeds number of fields")
-
- if not kwargs:
- fields_iter = iter(self._meta.concrete_fields)
- # The ordering of the zip calls matter - zip throws StopIteration
- # when an iter throws it. So if the first iter throws it, the second
- # is *not* consumed. We rely on this, so don't change the order
- # without changing the logic.
- for val, field in zip(args, fields_iter):
- setattr(self, field.attname, val)
- else:
- # Slower, kwargs-ready version.
- fields_iter = iter(self._meta.fields)
- for val, field in zip(args, fields_iter):
- setattr(self, field.attname, val)
- kwargs.pop(field.name, None)
- # Maintain compatibility with existing calls.
- if isinstance(field.rel, ManyToOneRel):
- kwargs.pop(field.attname, None)
-
- # Now we're left with the unprocessed fields that *must* come from
- # keywords, or default.
-
- for field in fields_iter:
- is_related_object = False
- # This slightly odd construct is so that we can access any
- # data-descriptor object (DeferredAttribute) without triggering its
- # __get__ method.
- if (field.attname not in kwargs and
- (isinstance(self.__class__.__dict__.get(field.attname), DeferredAttribute)
- or field.column is None)):
- # This field will be populated on request.
- continue
- if kwargs:
- if isinstance(field.rel, ForeignObjectRel):
- try:
- # Assume object instance was passed in.
- rel_obj = kwargs.pop(field.name)
- is_related_object = True
- except KeyError:
- try:
- # Object instance wasn't passed in -- must be an ID.
- val = kwargs.pop(field.attname)
- except KeyError:
- val = field.get_default()
- else:
- # Object instance was passed in. Special case: You can
- # pass in "None" for related objects if it's allowed.
- if rel_obj is None and field.null:
- val = None
- else:
- try:
- val = kwargs.pop(field.attname)
- except KeyError:
- # This is done with an exception rather than the
- # default argument on pop because we don't want
- # get_default() to be evaluated, and then not used.
- # Refs #12057.
- val = field.get_default()
- else:
- val = field.get_default()
-
- if is_related_object:
- # If we are passed a related instance, set it using the
- # field.name instead of field.attname (e.g. "user" instead of
- # "user_id") so that the object gets properly cached (and type
- # checked) by the RelatedObjectDescriptor.
- setattr(self, field.name, rel_obj)
- else:
- setattr(self, field.attname, val)
-
- if kwargs:
- for prop in list(kwargs):
- try:
- if isinstance(getattr(self.__class__, prop), property):
- setattr(self, prop, kwargs.pop(prop))
- except AttributeError:
- pass
- if kwargs:
- raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
- super(Model, self).__init__()
- signals.post_init.send(sender=self.__class__, instance=self)
-
- def __repr__(self):
- try:
- u = six.text_type(self)
- except (UnicodeEncodeError, UnicodeDecodeError):
- u = '[Bad Unicode data]'
- return force_str('<%s: %s>' % (self.__class__.__name__, u))
-
- def __str__(self):
- if six.PY2 and hasattr(self, '__unicode__'):
- return force_text(self).encode('utf-8')
- return '%s object' % self.__class__.__name__
-
- def __eq__(self, other):
- return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val()
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __hash__(self):
- return hash(self._get_pk_val())
-
- def __reduce__(self):
- """
- Provides pickling support. Normally, this just dispatches to Python's
- standard handling. However, for models with deferred field loading, we
- need to do things manually, as they're dynamically created classes and
- only module-level classes can be pickled by the default path.
- """
- data = self.__dict__
- if not self._deferred:
- class_id = self._meta.app_label, self._meta.object_name
- return model_unpickle, (class_id, [], simple_class_factory), data
- defers = []
- for field in self._meta.fields:
- if isinstance(self.__class__.__dict__.get(field.attname),
- DeferredAttribute):
- defers.append(field.attname)
- model = self._meta.proxy_for_model
- class_id = model._meta.app_label, model._meta.object_name
- return (model_unpickle, (class_id, defers, deferred_class_factory), data)
-
- def _get_pk_val(self, meta=None):
- if not meta:
- meta = self._meta
- return getattr(self, meta.pk.attname)
-
- def _set_pk_val(self, value):
- return setattr(self, self._meta.pk.attname, value)
-
- pk = property(_get_pk_val, _set_pk_val)
-
- def serializable_value(self, field_name):
- """
- Returns the value of the field name for this instance. If the field is
- a foreign key, returns the id value, instead of the object. If there's
- no Field object with this name on the model, the model attribute's
- value is returned directly.
-
- Used to serialize a field's value (in the serializer, or form output,
- for example). Normally, you would just access the attribute directly
- and not use this method.
- """
- try:
- field = self._meta.get_field_by_name(field_name)[0]
- except FieldDoesNotExist:
- return getattr(self, field_name)
- return getattr(self, field.attname)
-
- def save(self, force_insert=False, force_update=False, using=None,
- update_fields=None):
- """
- Saves the current instance. Override this in a subclass if you want to
- control the saving process.
-
- The 'force_insert' and 'force_update' parameters can be used to insist
- that the "save" must be an SQL insert or update (or equivalent for
- non-SQL backends), respectively. Normally, they should not be set.
- """
- using = using or router.db_for_write(self.__class__, instance=self)
- if force_insert and (force_update or update_fields):
- raise ValueError("Cannot force both insert and updating in model saving.")
-
- if update_fields is not None:
- # If update_fields is empty, skip the save. We do also check for
- # no-op saves later on for inheritance cases. This bailout is
- # still needed for skipping signal sending.
- if len(update_fields) == 0:
- return
-
- update_fields = frozenset(update_fields)
- field_names = set()
-
- for field in self._meta.fields:
- if not field.primary_key:
- field_names.add(field.name)
-
- if field.name != field.attname:
- field_names.add(field.attname)
-
- non_model_fields = update_fields.difference(field_names)
-
- if non_model_fields:
- raise ValueError("The following fields do not exist in this "
- "model or are m2m fields: %s"
- % ', '.join(non_model_fields))
-
- # If saving to the same database, and this model is deferred, then
- # automatically do a "update_fields" save on the loaded fields.
- elif not force_insert and self._deferred and using == self._state.db:
- field_names = set()
- for field in self._meta.concrete_fields:
- if not field.primary_key and not hasattr(field, 'through'):
- field_names.add(field.attname)
- deferred_fields = [
- f.attname for f in self._meta.fields
- if f.attname not in self.__dict__
- and isinstance(self.__class__.__dict__[f.attname],
- DeferredAttribute)]
-
- loaded_fields = field_names.difference(deferred_fields)
- if loaded_fields:
- update_fields = frozenset(loaded_fields)
-
- self.save_base(using=using, force_insert=force_insert,
- force_update=force_update, update_fields=update_fields)
- save.alters_data = True
-
- def save_base(self, raw=False, force_insert=False,
- force_update=False, using=None, update_fields=None):
- """
- Handles the parts of saving which should be done only once per save,
- yet need to be done in raw saves, too. This includes some sanity
- checks and signal sending.
-
- The 'raw' argument is telling save_base not to save any parent
- models and not to do any changes to the values before save. This
- is used by fixture loading.
- """
- using = using or router.db_for_write(self.__class__, instance=self)
- assert not (force_insert and (force_update or update_fields))
- assert update_fields is None or len(update_fields) > 0
- cls = origin = self.__class__
- # Skip proxies, but keep the origin as the proxy model.
- if cls._meta.proxy:
- cls = cls._meta.concrete_model
- meta = cls._meta
- if not meta.auto_created:
- signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using,
- update_fields=update_fields)
- with transaction.commit_on_success_unless_managed(using=using, savepoint=False):
- if not raw:
- self._save_parents(cls, using, update_fields)
- updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
- # Store the database on which the object was saved
- self._state.db = using
- # Once saved, this is no longer a to-be-added instance.
- self._state.adding = False
-
- # Signal that the save is complete
- if not meta.auto_created:
- signals.post_save.send(sender=origin, instance=self, created=(not updated),
- update_fields=update_fields, raw=raw, using=using)
-
- save_base.alters_data = True
-
- def _save_parents(self, cls, using, update_fields):
- """
- Saves all the parents of cls using values from self.
- """
- meta = cls._meta
- for parent, field in meta.parents.items():
- # Make sure the link fields are synced between parent and self.
- if (field and getattr(self, parent._meta.pk.attname) is None
- and getattr(self, field.attname) is not None):
- setattr(self, parent._meta.pk.attname, getattr(self, field.attname))
- self._save_parents(cls=parent, using=using, update_fields=update_fields)
- self._save_table(cls=parent, using=using, update_fields=update_fields)
- # Set the parent's PK value to self.
- if field:
- setattr(self, field.attname, self._get_pk_val(parent._meta))
- # Since we didn't have an instance of the parent handy set
- # attname directly, bypassing the descriptor. Invalidate
- # the related object cache, in case it's been accidentally
- # populated. A fresh instance will be re-built from the
- # database if necessary.
- cache_name = field.get_cache_name()
- if hasattr(self, cache_name):
- delattr(self, cache_name)
-
- def _save_table(self, raw=False, cls=None, force_insert=False,
- force_update=False, using=None, update_fields=None):
- """
- Does the heavy-lifting involved in saving. Updates or inserts the data
- for a single table.
- """
- meta = cls._meta
- non_pks = [f for f in meta.local_concrete_fields if not f.primary_key]
-
- if update_fields:
- non_pks = [f for f in non_pks
- if f.name in update_fields or f.attname in update_fields]
-
- pk_val = self._get_pk_val(meta)
- pk_set = pk_val is not None
- if not pk_set and (force_update or update_fields):
- raise ValueError("Cannot force an update in save() with no primary key.")
- updated = False
- # If possible, try an UPDATE. If that doesn't update anything, do an INSERT.
- if pk_set and not force_insert:
- base_qs = cls._base_manager.using(using)
- values = [(f, None, (getattr(self, f.attname) if raw else f.pre_save(self, False)))
- for f in non_pks]
- forced_update = update_fields or force_update
- updated = self._do_update(base_qs, using, pk_val, values, update_fields,
- forced_update)
- if force_update and not updated:
- raise DatabaseError("Forced update did not affect any rows.")
- if update_fields and not updated:
- raise DatabaseError("Save with update_fields did not affect any rows.")
- if not updated:
- if meta.order_with_respect_to:
- # If this is a model with an order_with_respect_to
- # autopopulate the _order field
- field = meta.order_with_respect_to
- order_value = cls._base_manager.using(using).filter(
- **{field.name: getattr(self, field.attname)}).count()
- self._order = order_value
-
- fields = meta.local_concrete_fields
- if not pk_set:
- fields = [f for f in fields if not isinstance(f, AutoField)]
-
- update_pk = bool(meta.has_auto_field and not pk_set)
- result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
- if update_pk:
- setattr(self, meta.pk.attname, result)
- return updated
-
- def _do_update(self, base_qs, using, pk_val, values, update_fields, forced_update):
- """
- This method will try to update the model. If the model was updated (in
- the sense that an update query was done and a matching row was found
- from the DB) the method will return True.
- """
- filtered = base_qs.filter(pk=pk_val)
- if not values:
- # We can end up here when saving a model in inheritance chain where
- # update_fields doesn't target any field in current model. In that
- # case we just say the update succeeded. Another case ending up here
- # is a model with just PK - in that case check that the PK still
- # exists.
- return update_fields is not None or filtered.exists()
- if self._meta.select_on_save and not forced_update:
- if filtered.exists():
- filtered._update(values)
- return True
- else:
- return False
- return filtered._update(values) > 0
-
- def _do_insert(self, manager, using, fields, update_pk, raw):
- """
- Do an INSERT. If update_pk is defined then this method should return
- the new pk for the model.
- """
- return manager._insert([self], fields=fields, return_id=update_pk,
- using=using, raw=raw)
-
- def delete(self, using=None):
- using = using or router.db_for_write(self.__class__, instance=self)
- assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
-
- collector = Collector(using=using)
- collector.collect([self])
- collector.delete()
-
- delete.alters_data = True
-
- def _get_FIELD_display(self, field):
- value = getattr(self, field.attname)
- return force_text(dict(field.flatchoices).get(value, value), strings_only=True)
-
- def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs):
- if not self.pk:
- raise ValueError("get_next/get_previous cannot be used on unsaved objects.")
- op = 'gt' if is_next else 'lt'
- order = '' if is_next else '-'
- param = force_text(getattr(self, field.attname))
- q = Q(**{'%s__%s' % (field.name, op): param})
- q = q | Q(**{field.name: param, 'pk__%s' % op: self.pk})
- qs = self.__class__._default_manager.using(self._state.db).filter(**kwargs).filter(q).order_by('%s%s' % (order, field.name), '%spk' % order)
- try:
- return qs[0]
- except IndexError:
- raise self.DoesNotExist("%s matching query does not exist." % self.__class__._meta.object_name)
-
- def _get_next_or_previous_in_order(self, is_next):
- cachename = "__%s_order_cache" % is_next
- if not hasattr(self, cachename):
- op = 'gt' if is_next else 'lt'
- order = '_order' if is_next else '-_order'
- order_field = self._meta.order_with_respect_to
- obj = self._default_manager.filter(**{
- order_field.name: getattr(self, order_field.attname)
- }).filter(**{
- '_order__%s' % op: self._default_manager.values('_order').filter(**{
- self._meta.pk.name: self.pk
- })
- }).order_by(order)[:1].get()
- setattr(self, cachename, obj)
- return getattr(self, cachename)
-
- def prepare_database_save(self, unused):
- if self.pk is None:
- raise ValueError("Unsaved model instance %r cannot be used in an ORM query." % self)
- return self.pk
-
- def clean(self):
- """
- Hook for doing any extra model-wide validation after clean() has been
- called on every field by self.clean_fields. Any ValidationError raised
- by this method will not be associated with a particular field; it will
- have a special-case association with the field defined by NON_FIELD_ERRORS.
- """
- pass
-
- def validate_unique(self, exclude=None):
- """
- Checks unique constraints on the model and raises ``ValidationError``
- if any failed.
- """
- unique_checks, date_checks = self._get_unique_checks(exclude=exclude)
-
- errors = self._perform_unique_checks(unique_checks)
- date_errors = self._perform_date_checks(date_checks)
-
- for k, v in date_errors.items():
- errors.setdefault(k, []).extend(v)
-
- if errors:
- raise ValidationError(errors)
-
- def _get_unique_checks(self, exclude=None):
- """
- Gather a list of checks to perform. Since validate_unique could be
- called from a ModelForm, some fields may have been excluded; we can't
- perform a unique check on a model that is missing fields involved
- in that check.
- Fields that did not validate should also be excluded, but they need
- to be passed in via the exclude argument.
- """
- if exclude is None:
- exclude = []
- unique_checks = []
-
- unique_togethers = [(self.__class__, self._meta.unique_together)]
- for parent_class in self._meta.parents.keys():
- if parent_class._meta.unique_together:
- unique_togethers.append((parent_class, parent_class._meta.unique_together))
-
- for model_class, unique_together in unique_togethers:
- for check in unique_together:
- for name in check:
- # If this is an excluded field, don't add this check.
- if name in exclude:
- break
- else:
- unique_checks.append((model_class, tuple(check)))
-
- # These are checks for the unique_for_<date/year/month>.
- date_checks = []
-
- # Gather a list of checks for fields declared as unique and add them to
- # the list of checks.
-
- fields_with_class = [(self.__class__, self._meta.local_fields)]
- for parent_class in self._meta.parents.keys():
- fields_with_class.append((parent_class, parent_class._meta.local_fields))
-
- for model_class, fields in fields_with_class:
- for f in fields:
- name = f.name
- if name in exclude:
- continue
- if f.unique:
- unique_checks.append((model_class, (name,)))
- if f.unique_for_date and f.unique_for_date not in exclude:
- date_checks.append((model_class, 'date', name, f.unique_for_date))
- if f.unique_for_year and f.unique_for_year not in exclude:
- date_checks.append((model_class, 'year', name, f.unique_for_year))
- if f.unique_for_month and f.unique_for_month not in exclude:
- date_checks.append((model_class, 'month', name, f.unique_for_month))
- return unique_checks, date_checks
-
- def _perform_unique_checks(self, unique_checks):
- errors = {}
-
- for model_class, unique_check in unique_checks:
- # Try to look up an existing object with the same values as this
- # object's values for all the unique field.
-
- lookup_kwargs = {}
- for field_name in unique_check:
- f = self._meta.get_field(field_name)
- lookup_value = getattr(self, f.attname)
- if lookup_value is None:
- # no value, skip the lookup
- continue
- if f.primary_key and not self._state.adding:
- # no need to check for unique primary key when editing
- continue
- lookup_kwargs[str(field_name)] = lookup_value
-
- # some fields were skipped, no reason to do the check
- if len(unique_check) != len(lookup_kwargs):
- continue
-
- qs = model_class._default_manager.filter(**lookup_kwargs)
-
- # Exclude the current object from the query if we are editing an
- # instance (as opposed to creating a new one)
- # Note that we need to use the pk as defined by model_class, not
- # self.pk. These can be different fields because model inheritance
- # allows single model to have effectively multiple primary keys.
- # Refs #17615.
- model_class_pk = self._get_pk_val(model_class._meta)
- if not self._state.adding and model_class_pk is not None:
- qs = qs.exclude(pk=model_class_pk)
- if qs.exists():
- if len(unique_check) == 1:
- key = unique_check[0]
- else:
- key = NON_FIELD_ERRORS
- errors.setdefault(key, []).append(self.unique_error_message(model_class, unique_check))
-
- return errors
-
- def _perform_date_checks(self, date_checks):
- errors = {}
- for model_class, lookup_type, field, unique_for in date_checks:
- lookup_kwargs = {}
- # there's a ticket to add a date lookup, we can remove this special
- # case if that makes it's way in
- date = getattr(self, unique_for)
- if date is None:
- continue
- if lookup_type == 'date':
- lookup_kwargs['%s__day' % unique_for] = date.day
- lookup_kwargs['%s__month' % unique_for] = date.month
- lookup_kwargs['%s__year' % unique_for] = date.year
- else:
- lookup_kwargs['%s__%s' % (unique_for, lookup_type)] = getattr(date, lookup_type)
- lookup_kwargs[field] = getattr(self, field)
-
- qs = model_class._default_manager.filter(**lookup_kwargs)
- # Exclude the current object from the query if we are editing an
- # instance (as opposed to creating a new one)
- if not self._state.adding and self.pk is not None:
- qs = qs.exclude(pk=self.pk)
-
- if qs.exists():
- errors.setdefault(field, []).append(
- self.date_error_message(lookup_type, field, unique_for)
- )
- return errors
-
- def date_error_message(self, lookup_type, field, unique_for):
- opts = self._meta
- return _("%(field_name)s must be unique for %(date_field)s %(lookup)s.") % {
- 'field_name': six.text_type(capfirst(opts.get_field(field).verbose_name)),
- 'date_field': six.text_type(capfirst(opts.get_field(unique_for).verbose_name)),
- 'lookup': lookup_type,
- }
-
- def unique_error_message(self, model_class, unique_check):
- opts = model_class._meta
- model_name = capfirst(opts.verbose_name)
-
- # A unique field
- if len(unique_check) == 1:
- field_name = unique_check[0]
- field = opts.get_field(field_name)
- field_label = capfirst(field.verbose_name)
- # Insert the error into the error dict, very sneaky
- return field.error_messages['unique'] % {
- 'model_name': six.text_type(model_name),
- 'field_label': six.text_type(field_label)
- }
- # unique_together
- else:
- field_labels = [capfirst(opts.get_field(f).verbose_name) for f in unique_check]
- field_labels = get_text_list(field_labels, _('and'))
- return _("%(model_name)s with this %(field_label)s already exists.") % {
- 'model_name': six.text_type(model_name),
- 'field_label': six.text_type(field_labels)
- }
-
- def full_clean(self, exclude=None, validate_unique=True):
- """
- Calls clean_fields, clean, and validate_unique, on the model,
- and raises a ``ValidationError`` for any errors that occurred.
- """
- errors = {}
- if exclude is None:
- exclude = []
-
- try:
- self.clean_fields(exclude=exclude)
- except ValidationError as e:
- errors = e.update_error_dict(errors)
-
- # Form.clean() is run even if other validation fails, so do the
- # same with Model.clean() for consistency.
- try:
- self.clean()
- except ValidationError as e:
- errors = e.update_error_dict(errors)
-
- # Run unique checks, but only for fields that passed validation.
- if validate_unique:
- for name in errors.keys():
- if name != NON_FIELD_ERRORS and name not in exclude:
- exclude.append(name)
- try:
- self.validate_unique(exclude=exclude)
- except ValidationError as e:
- errors = e.update_error_dict(errors)
-
- if errors:
- raise ValidationError(errors)
-
- def clean_fields(self, exclude=None):
- """
- Cleans all fields and raises a ValidationError containing message_dict
- of all validation errors if any occur.
- """
- if exclude is None:
- exclude = []
-
- errors = {}
- for f in self._meta.fields:
- if f.name in exclude:
- continue
- # Skip validation for empty fields with blank=True. The developer
- # is responsible for making sure they have a valid value.
- raw_value = getattr(self, f.attname)
- if f.blank and raw_value in f.empty_values:
- continue
- try:
- setattr(self, f.attname, f.clean(raw_value, self))
- except ValidationError as e:
- errors[f.name] = e.error_list
-
- if errors:
- raise ValidationError(errors)
-
-
-############################################
-# HELPER FUNCTIONS (CURRIED MODEL METHODS) #
-############################################
-
-# ORDERING METHODS #########################
-
-def method_set_order(ordered_obj, self, id_list, using=None):
- if using is None:
- using = DEFAULT_DB_ALIAS
- rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
- order_name = ordered_obj._meta.order_with_respect_to.name
- # FIXME: It would be nice if there was an "update many" version of update
- # for situations like this.
- with transaction.commit_on_success_unless_managed(using=using):
- for i, j in enumerate(id_list):
- ordered_obj.objects.filter(**{'pk': j, order_name: rel_val}).update(_order=i)
-
-
-def method_get_order(ordered_obj, self):
- rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
- order_name = ordered_obj._meta.order_with_respect_to.name
- pk_name = ordered_obj._meta.pk.name
- return [r[pk_name] for r in
- ordered_obj.objects.filter(**{order_name: rel_val}).values(pk_name)]
-
-
-##############################################
-# HELPER FUNCTIONS (CURRIED MODEL FUNCTIONS) #
-##############################################
-
-def get_absolute_url(opts, func, self, *args, **kwargs):
- return settings.ABSOLUTE_URL_OVERRIDES.get('%s.%s' % (opts.app_label, opts.model_name), func)(self, *args, **kwargs)
-
-
-########
-# MISC #
-########
-
-class Empty(object):
- pass
-
-def simple_class_factory(model, attrs):
- """
- Needed for dynamic classes.
- """
- return model
-
-def model_unpickle(model_id, attrs, factory):
- """
- Used to unpickle Model subclasses with deferred fields.
- """
- if isinstance(model_id, tuple):
- model = get_model(*model_id)
- else:
- # Backwards compat - the model was cached directly in earlier versions.
- model = model_id
- cls = factory(model, attrs)
- return cls.__new__(cls)
-model_unpickle.__safe_for_unpickle__ = True
-
-
-def unpickle_inner_exception(klass, exception_name):
- # Get the exception class from the class it is attached to:
- exception = getattr(klass, exception_name)
- return exception.__new__(exception)
diff --git a/lib/python2.7/site-packages/django/db/models/constants.py b/lib/python2.7/site-packages/django/db/models/constants.py
deleted file mode 100644
index a7e6c25..0000000
--- a/lib/python2.7/site-packages/django/db/models/constants.py
+++ /dev/null
@@ -1,6 +0,0 @@
-"""
-Constants used across the ORM in general.
-"""
-
-# Separator used to split filter strings apart.
-LOOKUP_SEP = '__'
diff --git a/lib/python2.7/site-packages/django/db/models/deletion.py b/lib/python2.7/site-packages/django/db/models/deletion.py
deleted file mode 100644
index e0bfb9d..0000000
--- a/lib/python2.7/site-packages/django/db/models/deletion.py
+++ /dev/null
@@ -1,292 +0,0 @@
-from operator import attrgetter
-
-from django.db import connections, transaction, IntegrityError
-from django.db.models import signals, sql
-from django.utils.datastructures import SortedDict
-from django.utils import six
-
-
-class ProtectedError(IntegrityError):
- def __init__(self, msg, protected_objects):
- self.protected_objects = protected_objects
- super(ProtectedError, self).__init__(msg, protected_objects)
-
-
-def CASCADE(collector, field, sub_objs, using):
- collector.collect(sub_objs, source=field.rel.to,
- source_attr=field.name, nullable=field.null)
- if field.null and not connections[using].features.can_defer_constraint_checks:
- collector.add_field_update(field, None, sub_objs)
-
-
-def PROTECT(collector, field, sub_objs, using):
- raise ProtectedError("Cannot delete some instances of model '%s' because "
- "they are referenced through a protected foreign key: '%s.%s'" % (
- field.rel.to.__name__, sub_objs[0].__class__.__name__, field.name
- ),
- sub_objs
- )
-
-
-def SET(value):
- if callable(value):
- def set_on_delete(collector, field, sub_objs, using):
- collector.add_field_update(field, value(), sub_objs)
- else:
- def set_on_delete(collector, field, sub_objs, using):
- collector.add_field_update(field, value, sub_objs)
- return set_on_delete
-
-
-SET_NULL = SET(None)
-
-
-def SET_DEFAULT(collector, field, sub_objs, using):
- collector.add_field_update(field, field.get_default(), sub_objs)
-
-
-def DO_NOTHING(collector, field, sub_objs, using):
- pass
-
-
-class Collector(object):
- def __init__(self, using):
- self.using = using
- # Initially, {model: set([instances])}, later values become lists.
- self.data = {}
- self.field_updates = {} # {model: {(field, value): set([instances])}}
- # fast_deletes is a list of queryset-likes that can be deleted without
- # fetching the objects into memory.
- self.fast_deletes = []
-
- # Tracks deletion-order dependency for databases without transactions
- # or ability to defer constraint checks. Only concrete model classes
- # should be included, as the dependencies exist only between actual
- # database tables; proxy models are represented here by their concrete
- # parent.
- self.dependencies = {} # {model: set([models])}
-
- def add(self, objs, source=None, nullable=False, reverse_dependency=False):
- """
- Adds 'objs' to the collection of objects to be deleted. If the call is
- the result of a cascade, 'source' should be the model that caused it,
- and 'nullable' should be set to True if the relation can be null.
-
- Returns a list of all objects that were not already collected.
- """
- if not objs:
- return []
- new_objs = []
- model = objs[0].__class__
- instances = self.data.setdefault(model, set())
- for obj in objs:
- if obj not in instances:
- new_objs.append(obj)
- instances.update(new_objs)
- # Nullable relationships can be ignored -- they are nulled out before
- # deleting, and therefore do not affect the order in which objects have
- # to be deleted.
- if source is not None and not nullable:
- if reverse_dependency:
- source, model = model, source
- self.dependencies.setdefault(
- source._meta.concrete_model, set()).add(model._meta.concrete_model)
- return new_objs
-
- def add_field_update(self, field, value, objs):
- """
- Schedules a field update. 'objs' must be a homogenous iterable
- collection of model instances (e.g. a QuerySet).
- """
- if not objs:
- return
- model = objs[0].__class__
- self.field_updates.setdefault(
- model, {}).setdefault(
- (field, value), set()).update(objs)
-
- def can_fast_delete(self, objs, from_field=None):
- """
- Determines if the objects in the given queryset-like can be
- fast-deleted. This can be done if there are no cascades, no
- parents and no signal listeners for the object class.
-
- The 'from_field' tells where we are coming from - we need this to
- determine if the objects are in fact to be deleted. Allows also
- skipping parent -> child -> parent chain preventing fast delete of
- the child.
- """
- if from_field and from_field.rel.on_delete is not CASCADE:
- return False
- if not (hasattr(objs, 'model') and hasattr(objs, '_raw_delete')):
- return False
- model = objs.model
- if (signals.pre_delete.has_listeners(model)
- or signals.post_delete.has_listeners(model)
- or signals.m2m_changed.has_listeners(model)):
- return False
- # The use of from_field comes from the need to avoid cascade back to
- # parent when parent delete is cascading to child.
- opts = model._meta
- if any(link != from_field for link in opts.concrete_model._meta.parents.values()):
- return False
- # Foreign keys pointing to this model, both from m2m and other
- # models.
- for related in opts.get_all_related_objects(
- include_hidden=True, include_proxy_eq=True):
- if related.field.rel.on_delete is not DO_NOTHING:
- return False
- # GFK deletes
- for relation in opts.many_to_many:
- if not relation.rel.through:
- return False
- return True
-
- def collect(self, objs, source=None, nullable=False, collect_related=True,
- source_attr=None, reverse_dependency=False):
- """
- Adds 'objs' to the collection of objects to be deleted as well as all
- parent instances. 'objs' must be a homogenous iterable collection of
- model instances (e.g. a QuerySet). If 'collect_related' is True,
- related objects will be handled by their respective on_delete handler.
-
- If the call is the result of a cascade, 'source' should be the model
- that caused it and 'nullable' should be set to True, if the relation
- can be null.
-
- If 'reverse_dependency' is True, 'source' will be deleted before the
- current model, rather than after. (Needed for cascading to parent
- models, the one case in which the cascade follows the forwards
- direction of an FK rather than the reverse direction.)
- """
- if self.can_fast_delete(objs):
- self.fast_deletes.append(objs)
- return
- new_objs = self.add(objs, source, nullable,
- reverse_dependency=reverse_dependency)
- if not new_objs:
- return
-
- model = new_objs[0].__class__
-
- # Recursively collect concrete model's parent models, but not their
- # related objects. These will be found by meta.get_all_related_objects()
- concrete_model = model._meta.concrete_model
- for ptr in six.itervalues(concrete_model._meta.parents):
- if ptr:
- # FIXME: This seems to be buggy and execute a query for each
- # parent object fetch. We have the parent data in the obj,
- # but we don't have a nice way to turn that data into parent
- # object instance.
- parent_objs = [getattr(obj, ptr.name) for obj in new_objs]
- self.collect(parent_objs, source=model,
- source_attr=ptr.rel.related_name,
- collect_related=False,
- reverse_dependency=True)
-
- if collect_related:
- for related in model._meta.get_all_related_objects(
- include_hidden=True, include_proxy_eq=True):
- field = related.field
- if field.rel.on_delete == DO_NOTHING:
- continue
- sub_objs = self.related_objects(related, new_objs)
- if self.can_fast_delete(sub_objs, from_field=field):
- self.fast_deletes.append(sub_objs)
- elif sub_objs:
- field.rel.on_delete(self, field, sub_objs, self.using)
- for field in model._meta.virtual_fields:
- if hasattr(field, 'bulk_related_objects'):
- # Its something like generic foreign key.
- sub_objs = field.bulk_related_objects(new_objs, self.using)
- self.collect(sub_objs,
- source=model,
- source_attr=field.rel.related_name,
- nullable=True)
-
- def related_objects(self, related, objs):
- """
- Gets a QuerySet of objects related to ``objs`` via the relation ``related``.
-
- """
- return related.model._base_manager.using(self.using).filter(
- **{"%s__in" % related.field.name: objs}
- )
-
- def instances_with_model(self):
- for model, instances in six.iteritems(self.data):
- for obj in instances:
- yield model, obj
-
- def sort(self):
- sorted_models = []
- concrete_models = set()
- models = list(self.data)
- while len(sorted_models) < len(models):
- found = False
- for model in models:
- if model in sorted_models:
- continue
- dependencies = self.dependencies.get(model._meta.concrete_model)
- if not (dependencies and dependencies.difference(concrete_models)):
- sorted_models.append(model)
- concrete_models.add(model._meta.concrete_model)
- found = True
- if not found:
- return
- self.data = SortedDict([(model, self.data[model])
- for model in sorted_models])
-
- def delete(self):
- # sort instance collections
- for model, instances in self.data.items():
- self.data[model] = sorted(instances, key=attrgetter("pk"))
-
- # if possible, bring the models in an order suitable for databases that
- # don't support transactions or cannot defer constraint checks until the
- # end of a transaction.
- self.sort()
-
- with transaction.commit_on_success_unless_managed(using=self.using):
- # send pre_delete signals
- for model, obj in self.instances_with_model():
- if not model._meta.auto_created:
- signals.pre_delete.send(
- sender=model, instance=obj, using=self.using
- )
-
- # fast deletes
- for qs in self.fast_deletes:
- qs._raw_delete(using=self.using)
-
- # update fields
- for model, instances_for_fieldvalues in six.iteritems(self.field_updates):
- query = sql.UpdateQuery(model)
- for (field, value), instances in six.iteritems(instances_for_fieldvalues):
- query.update_batch([obj.pk for obj in instances],
- {field.name: value}, self.using)
-
- # reverse instance collections
- for instances in six.itervalues(self.data):
- instances.reverse()
-
- # delete instances
- for model, instances in six.iteritems(self.data):
- query = sql.DeleteQuery(model)
- pk_list = [obj.pk for obj in instances]
- query.delete_batch(pk_list, self.using)
-
- if not model._meta.auto_created:
- for obj in instances:
- signals.post_delete.send(
- sender=model, instance=obj, using=self.using
- )
-
- # update collected instances
- for model, instances_for_fieldvalues in six.iteritems(self.field_updates):
- for (field, value), instances in six.iteritems(instances_for_fieldvalues):
- for obj in instances:
- setattr(obj, field.attname, value)
- for model, instances in six.iteritems(self.data):
- for instance in instances:
- setattr(instance, model._meta.pk.attname, None)
diff --git a/lib/python2.7/site-packages/django/db/models/expressions.py b/lib/python2.7/site-packages/django/db/models/expressions.py
deleted file mode 100644
index 6e0f3c4..0000000
--- a/lib/python2.7/site-packages/django/db/models/expressions.py
+++ /dev/null
@@ -1,186 +0,0 @@
-import datetime
-
-from django.db.models.aggregates import refs_aggregate
-from django.db.models.constants import LOOKUP_SEP
-from django.utils import tree
-
-class ExpressionNode(tree.Node):
- """
- Base class for all query expressions.
- """
- # Arithmetic connectors
- ADD = '+'
- SUB = '-'
- MUL = '*'
- DIV = '/'
- MOD = '%%' # This is a quoted % operator - it is quoted
- # because it can be used in strings that also
- # have parameter substitution.
-
- # Bitwise operators - note that these are generated by .bitand()
- # and .bitor(), the '&' and '|' are reserved for boolean operator
- # usage.
- BITAND = '&'
- BITOR = '|'
-
- def __init__(self, children=None, connector=None, negated=False):
- if children is not None and len(children) > 1 and connector is None:
- raise TypeError('You have to specify a connector.')
- super(ExpressionNode, self).__init__(children, connector, negated)
-
- def _combine(self, other, connector, reversed, node=None):
- if isinstance(other, datetime.timedelta):
- return DateModifierNode([self, other], connector)
-
- if reversed:
- obj = ExpressionNode([other], connector)
- obj.add(node or self, connector)
- else:
- obj = node or ExpressionNode([self], connector)
- obj.add(other, connector)
- return obj
-
- def contains_aggregate(self, existing_aggregates):
- if self.children:
- return any(child.contains_aggregate(existing_aggregates)
- for child in self.children
- if hasattr(child, 'contains_aggregate'))
- else:
- return refs_aggregate(self.name.split(LOOKUP_SEP),
- existing_aggregates)
-
- def prepare_database_save(self, unused):
- return self
-
- ###################
- # VISITOR METHODS #
- ###################
-
- def prepare(self, evaluator, query, allow_joins):
- return evaluator.prepare_node(self, query, allow_joins)
-
- def evaluate(self, evaluator, qn, connection):
- return evaluator.evaluate_node(self, qn, connection)
-
- #############
- # OPERATORS #
- #############
-
- def __add__(self, other):
- return self._combine(other, self.ADD, False)
-
- def __sub__(self, other):
- return self._combine(other, self.SUB, False)
-
- def __mul__(self, other):
- return self._combine(other, self.MUL, False)
-
- def __truediv__(self, other):
- return self._combine(other, self.DIV, False)
-
- def __div__(self, other): # Python 2 compatibility
- return type(self).__truediv__(self, other)
-
- def __mod__(self, other):
- return self._combine(other, self.MOD, False)
-
- def __and__(self, other):
- raise NotImplementedError(
- "Use .bitand() and .bitor() for bitwise logical operations."
- )
-
- def bitand(self, other):
- return self._combine(other, self.BITAND, False)
-
- def __or__(self, other):
- raise NotImplementedError(
- "Use .bitand() and .bitor() for bitwise logical operations."
- )
-
- def bitor(self, other):
- return self._combine(other, self.BITOR, False)
-
- def __radd__(self, other):
- return self._combine(other, self.ADD, True)
-
- def __rsub__(self, other):
- return self._combine(other, self.SUB, True)
-
- def __rmul__(self, other):
- return self._combine(other, self.MUL, True)
-
- def __rtruediv__(self, other):
- return self._combine(other, self.DIV, True)
-
- def __rdiv__(self, other): # Python 2 compatibility
- return type(self).__rtruediv__(self, other)
-
- def __rmod__(self, other):
- return self._combine(other, self.MOD, True)
-
- def __rand__(self, other):
- raise NotImplementedError(
- "Use .bitand() and .bitor() for bitwise logical operations."
- )
-
- def __ror__(self, other):
- raise NotImplementedError(
- "Use .bitand() and .bitor() for bitwise logical operations."
- )
-
-class F(ExpressionNode):
- """
- An expression representing the value of the given field.
- """
- def __init__(self, name):
- super(F, self).__init__(None, None, False)
- self.name = name
-
- def __deepcopy__(self, memodict):
- obj = super(F, self).__deepcopy__(memodict)
- obj.name = self.name
- return obj
-
- def prepare(self, evaluator, query, allow_joins):
- return evaluator.prepare_leaf(self, query, allow_joins)
-
- def evaluate(self, evaluator, qn, connection):
- return evaluator.evaluate_leaf(self, qn, connection)
-
-class DateModifierNode(ExpressionNode):
- """
- Node that implements the following syntax:
- filter(end_date__gt=F('start_date') + datetime.timedelta(days=3, seconds=200))
-
- which translates into:
- POSTGRES:
- WHERE end_date > (start_date + INTERVAL '3 days 200 seconds')
-
- MYSQL:
- WHERE end_date > (start_date + INTERVAL '3 0:0:200:0' DAY_MICROSECOND)
-
- ORACLE:
- WHERE end_date > (start_date + INTERVAL '3 00:03:20.000000' DAY(1) TO SECOND(6))
-
- SQLITE:
- WHERE end_date > django_format_dtdelta(start_date, "+" "3", "200", "0")
- (A custom function is used in order to preserve six digits of fractional
- second information on sqlite, and to format both date and datetime values.)
-
- Note that microsecond comparisons are not well supported with MySQL, since
- MySQL does not store microsecond information.
-
- Only adding and subtracting timedeltas is supported, attempts to use other
- operations raise a TypeError.
- """
- def __init__(self, children, connector, negated=False):
- if len(children) != 2:
- raise TypeError('Must specify a node and a timedelta.')
- if not isinstance(children[1], datetime.timedelta):
- raise TypeError('Second child must be a timedelta.')
- if connector not in (self.ADD, self.SUB):
- raise TypeError('Connector must be + or -, not %s' % connector)
- super(DateModifierNode, self).__init__(children, connector, negated)
-
- def evaluate(self, evaluator, qn, connection):
- return evaluator.evaluate_date_modifier_node(self, qn, connection)
diff --git a/lib/python2.7/site-packages/django/db/models/fields/__init__.py b/lib/python2.7/site-packages/django/db/models/fields/__init__.py
deleted file mode 100644
index c10e2b1..0000000
--- a/lib/python2.7/site-packages/django/db/models/fields/__init__.py
+++ /dev/null
@@ -1,1438 +0,0 @@
-from __future__ import unicode_literals
-
-import copy
-import datetime
-import decimal
-import math
-import warnings
-from base64 import b64decode, b64encode
-from itertools import tee
-
-from django.db import connection
-from django.db.models.loading import get_model
-from django.db.models.query_utils import QueryWrapper
-from django.conf import settings
-from django import forms
-from django.core import exceptions, validators
-from django.utils.datastructures import DictWrapper
-from django.utils.dateparse import parse_date, parse_datetime, parse_time
-from django.utils.functional import curry, total_ordering
-from django.utils.itercompat import is_iterator
-from django.utils.text import capfirst
-from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import smart_text, force_text, force_bytes
-from django.utils.ipv6 import clean_ipv6_address
-from django.utils import six
-
-class Empty(object):
- pass
-
-class NOT_PROVIDED:
- pass
-
-# The values to use for "blank" in SelectFields. Will be appended to the start
-# of most "choices" lists.
-BLANK_CHOICE_DASH = [("", "---------")]
-
-def _load_field(app_label, model_name, field_name):
- return get_model(app_label, model_name)._meta.get_field_by_name(field_name)[0]
-
-class FieldDoesNotExist(Exception):
- pass
-
-# A guide to Field parameters:
-#
-# * name: The name of the field specifed in the model.
-# * attname: The attribute to use on the model object. This is the same as
-# "name", except in the case of ForeignKeys, where "_id" is
-# appended.
-# * db_column: The db_column specified in the model (or None).
-# * column: The database column for this field. This is the same as
-# "attname", except if db_column is specified.
-#
-# Code that introspects values, or does other dynamic things, should use
-# attname. For example, this gets the primary key value of object "obj":
-#
-# getattr(obj, opts.pk.attname)
-
-def _empty(of_cls):
- new = Empty()
- new.__class__ = of_cls
- return new
-
-@total_ordering
-class Field(object):
- """Base class for all field types"""
-
- # Designates whether empty strings fundamentally are allowed at the
- # database level.
- empty_strings_allowed = True
- empty_values = list(validators.EMPTY_VALUES)
-
- # These track each time a Field instance is created. Used to retain order.
- # The auto_creation_counter is used for fields that Django implicitly
- # creates, creation_counter is used for all user-specified fields.
- creation_counter = 0
- auto_creation_counter = -1
- default_validators = [] # Default set of validators
- default_error_messages = {
- 'invalid_choice': _('Value %(value)r is not a valid choice.'),
- 'null': _('This field cannot be null.'),
- 'blank': _('This field cannot be blank.'),
- 'unique': _('%(model_name)s with this %(field_label)s '
- 'already exists.'),
- }
-
- # Generic field type description, usually overriden by subclasses
- def _description(self):
- return _('Field of type: %(field_type)s') % {
- 'field_type': self.__class__.__name__
- }
- description = property(_description)
-
- def __init__(self, verbose_name=None, name=None, primary_key=False,
- max_length=None, unique=False, blank=False, null=False,
- db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
- serialize=True, unique_for_date=None, unique_for_month=None,
- unique_for_year=None, choices=None, help_text='', db_column=None,
- db_tablespace=None, auto_created=False, validators=[],
- error_messages=None):
- self.name = name
- self.verbose_name = verbose_name
- self.primary_key = primary_key
- self.max_length, self._unique = max_length, unique
- self.blank, self.null = blank, null
- self.rel = rel
- self.default = default
- self.editable = editable
- self.serialize = serialize
- self.unique_for_date, self.unique_for_month = (unique_for_date,
- unique_for_month)
- self.unique_for_year = unique_for_year
- self._choices = choices or []
- self.help_text = help_text
- self.db_column = db_column
- self.db_tablespace = db_tablespace or settings.DEFAULT_INDEX_TABLESPACE
- self.auto_created = auto_created
-
- # Set db_index to True if the field has a relationship and doesn't
- # explicitly set db_index.
- self.db_index = db_index
-
- # Adjust the appropriate creation counter, and save our local copy.
- if auto_created:
- self.creation_counter = Field.auto_creation_counter
- Field.auto_creation_counter -= 1
- else:
- self.creation_counter = Field.creation_counter
- Field.creation_counter += 1
-
- self.validators = self.default_validators + validators
-
- messages = {}
- for c in reversed(self.__class__.__mro__):
- messages.update(getattr(c, 'default_error_messages', {}))
- messages.update(error_messages or {})
- self.error_messages = messages
-
- def __eq__(self, other):
- # Needed for @total_ordering
- if isinstance(other, Field):
- return self.creation_counter == other.creation_counter
- return NotImplemented
-
- def __lt__(self, other):
- # This is needed because bisect does not take a comparison function.
- if isinstance(other, Field):
- return self.creation_counter < other.creation_counter
- return NotImplemented
-
- def __hash__(self):
- return hash(self.creation_counter)
-
- def __deepcopy__(self, memodict):
- # We don't have to deepcopy very much here, since most things are not
- # intended to be altered after initial creation.
- obj = copy.copy(self)
- if self.rel:
- obj.rel = copy.copy(self.rel)
- if hasattr(self.rel, 'field') and self.rel.field is self:
- obj.rel.field = obj
- memodict[id(self)] = obj
- return obj
-
- def __copy__(self):
- # We need to avoid hitting __reduce__, so define this
- # slightly weird copy construct.
- obj = Empty()
- obj.__class__ = self.__class__
- obj.__dict__ = self.__dict__.copy()
- return obj
-
- def __reduce__(self):
- """
- Pickling should return the model._meta.fields instance of the field,
- not a new copy of that field. So, we use the app cache to load the
- model and then the field back.
- """
- if not hasattr(self, 'model'):
- # Fields are sometimes used without attaching them to models (for
- # example in aggregation). In this case give back a plain field
- # instance. The code below will create a new empty instance of
- # class self.__class__, then update its dict with self.__dict__
- # values - so, this is very close to normal pickle.
- return _empty, (self.__class__,), self.__dict__
- if self.model._deferred:
- # Deferred model will not be found from the app cache. This could
- # be fixed by reconstructing the deferred model on unpickle.
- raise RuntimeError("Fields of deferred models can't be reduced")
- return _load_field, (self.model._meta.app_label, self.model._meta.object_name,
- self.name)
-
- def to_python(self, value):
- """
- Converts the input value into the expected Python data type, raising
- django.core.exceptions.ValidationError if the data can't be converted.
- Returns the converted value. Subclasses should override this.
- """
- return value
-
- def run_validators(self, value):
- if value in self.empty_values:
- return
-
- errors = []
- for v in self.validators:
- try:
- v(value)
- except exceptions.ValidationError as e:
- if hasattr(e, 'code') and e.code in self.error_messages:
- e.message = self.error_messages[e.code]
- errors.extend(e.error_list)
-
- if errors:
- raise exceptions.ValidationError(errors)
-
- def validate(self, value, model_instance):
- """
- Validates value and throws ValidationError. Subclasses should override
- this to provide validation logic.
- """
- if not self.editable:
- # Skip validation for non-editable fields.
- return
-
- if self._choices and value not in self.empty_values:
- for option_key, option_value in self.choices:
- if isinstance(option_value, (list, tuple)):
- # This is an optgroup, so look inside the group for
- # options.
- for optgroup_key, optgroup_value in option_value:
- if value == optgroup_key:
- return
- elif value == option_key:
- return
- raise exceptions.ValidationError(
- self.error_messages['invalid_choice'],
- code='invalid_choice',
- params={'value': value},
- )
-
- if value is None and not self.null:
- raise exceptions.ValidationError(self.error_messages['null'], code='null')
-
- if not self.blank and value in self.empty_values:
- raise exceptions.ValidationError(self.error_messages['blank'], code='blank')
-
- def clean(self, value, model_instance):
- """
- Convert the value's type and run validation. Validation errors
- from to_python and validate are propagated. The correct value is
- returned if no error is raised.
- """
- value = self.to_python(value)
- self.validate(value, model_instance)
- self.run_validators(value)
- return value
-
- def db_type(self, connection):
- """
- Returns the database column data type for this field, for the provided
- connection.
- """
- # The default implementation of this method looks at the
- # backend-specific DATA_TYPES dictionary, looking up the field by its
- # "internal type".
- #
- # A Field class can implement the get_internal_type() method to specify
- # which *preexisting* Django Field class it's most similar to -- i.e.,
- # a custom field might be represented by a TEXT column type, which is
- # the same as the TextField Django field type, which means the custom
- # field's get_internal_type() returns 'TextField'.
- #
- # But the limitation of the get_internal_type() / data_types approach
- # is that it cannot handle database column types that aren't already
- # mapped to one of the built-in Django field types. In this case, you
- # can implement db_type() instead of get_internal_type() to specify
- # exactly which wacky database column type you want to use.
- data = DictWrapper(self.__dict__, connection.ops.quote_name, "qn_")
- try:
- return (connection.creation.data_types[self.get_internal_type()]
- % data)
- except KeyError:
- return None
-
- @property
- def unique(self):
- return self._unique or self.primary_key
-
- def set_attributes_from_name(self, name):
- if not self.name:
- self.name = name
- self.attname, self.column = self.get_attname_column()
- if self.verbose_name is None and self.name:
- self.verbose_name = self.name.replace('_', ' ')
-
- def contribute_to_class(self, cls, name, virtual_only=False):
- self.set_attributes_from_name(name)
- self.model = cls
- if virtual_only:
- cls._meta.add_virtual_field(self)
- else:
- cls._meta.add_field(self)
- if self.choices:
- setattr(cls, 'get_%s_display' % self.name,
- curry(cls._get_FIELD_display, field=self))
-
- def get_attname(self):
- return self.name
-
- def get_attname_column(self):
- attname = self.get_attname()
- column = self.db_column or attname
- return attname, column
-
- def get_cache_name(self):
- return '_%s_cache' % self.name
-
- def get_internal_type(self):
- return self.__class__.__name__
-
- def pre_save(self, model_instance, add):
- """
- Returns field's value just before saving.
- """
- return getattr(model_instance, self.attname)
-
- def get_prep_value(self, value):
- """
- Perform preliminary non-db specific value checks and conversions.
- """
- return value
-
- def get_db_prep_value(self, value, connection, prepared=False):
- """Returns field's value prepared for interacting with the database
- backend.
-
- Used by the default implementations of ``get_db_prep_save``and
- `get_db_prep_lookup```
- """
- if not prepared:
- value = self.get_prep_value(value)
- return value
-
- def get_db_prep_save(self, value, connection):
- """
- Returns field's value prepared for saving into a database.
- """
- return self.get_db_prep_value(value, connection=connection,
- prepared=False)
-
- def get_prep_lookup(self, lookup_type, value):
- """
- Perform preliminary non-db specific lookup checks and conversions
- """
- if hasattr(value, 'prepare'):
- return value.prepare()
- if hasattr(value, '_prepare'):
- return value._prepare()
-
- if lookup_type in (
- 'iexact', 'contains', 'icontains',
- 'startswith', 'istartswith', 'endswith', 'iendswith',
- 'month', 'day', 'week_day', 'hour', 'minute', 'second',
- 'isnull', 'search', 'regex', 'iregex',
- ):
- return value
- elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'):
- return self.get_prep_value(value)
- elif lookup_type in ('range', 'in'):
- return [self.get_prep_value(v) for v in value]
- elif lookup_type == 'year':
- try:
- return int(value)
- except ValueError:
- raise ValueError("The __year lookup type requires an integer "
- "argument")
-
- raise TypeError("Field has invalid lookup: %s" % lookup_type)
-
- def get_db_prep_lookup(self, lookup_type, value, connection,
- prepared=False):
- """
- Returns field's value prepared for database lookup.
- """
- if not prepared:
- value = self.get_prep_lookup(lookup_type, value)
- prepared = True
- if hasattr(value, 'get_compiler'):
- value = value.get_compiler(connection=connection)
- if hasattr(value, 'as_sql') or hasattr(value, '_as_sql'):
- # If the value has a relabeled_clone method it means the
- # value will be handled later on.
- if hasattr(value, 'relabeled_clone'):
- return value
- if hasattr(value, 'as_sql'):
- sql, params = value.as_sql()
- else:
- sql, params = value._as_sql(connection=connection)
- return QueryWrapper(('(%s)' % sql), params)
-
- if lookup_type in ('month', 'day', 'week_day', 'hour', 'minute',
- 'second', 'search', 'regex', 'iregex'):
- return [value]
- elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'):
- return [self.get_db_prep_value(value, connection=connection,
- prepared=prepared)]
- elif lookup_type in ('range', 'in'):
- return [self.get_db_prep_value(v, connection=connection,
- prepared=prepared) for v in value]
- elif lookup_type in ('contains', 'icontains'):
- return ["%%%s%%" % connection.ops.prep_for_like_query(value)]
- elif lookup_type == 'iexact':
- return [connection.ops.prep_for_iexact_query(value)]
- elif lookup_type in ('startswith', 'istartswith'):
- return ["%s%%" % connection.ops.prep_for_like_query(value)]
- elif lookup_type in ('endswith', 'iendswith'):
- return ["%%%s" % connection.ops.prep_for_like_query(value)]
- elif lookup_type == 'isnull':
- return []
- elif lookup_type == 'year':
- if isinstance(self, DateTimeField):
- return connection.ops.year_lookup_bounds_for_datetime_field(value)
- elif isinstance(self, DateField):
- return connection.ops.year_lookup_bounds_for_date_field(value)
- else:
- return [value] # this isn't supposed to happen
-
- def has_default(self):
- """
- Returns a boolean of whether this field has a default value.
- """
- return self.default is not NOT_PROVIDED
-
- def get_default(self):
- """
- Returns the default value for this field.
- """
- if self.has_default():
- if callable(self.default):
- return self.default()
- return force_text(self.default, strings_only=True)
- if (not self.empty_strings_allowed or (self.null and
- not connection.features.interprets_empty_strings_as_nulls)):
- return None
- return ""
-
- def get_validator_unique_lookup_type(self):
- return '%s__exact' % self.name
-
- def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
- """Returns choices with a default blank choices included, for use
- as SelectField choices for this field."""
- first_choice = blank_choice if include_blank else []
- if self.choices:
- return first_choice + list(self.choices)
- rel_model = self.rel.to
- if hasattr(self.rel, 'get_related_field'):
- lst = [(getattr(x, self.rel.get_related_field().attname),
- smart_text(x))
- for x in rel_model._default_manager.complex_filter(
- self.rel.limit_choices_to)]
- else:
- lst = [(x._get_pk_val(), smart_text(x))
- for x in rel_model._default_manager.complex_filter(
- self.rel.limit_choices_to)]
- return first_choice + lst
-
- def get_choices_default(self):
- return self.get_choices()
-
- def get_flatchoices(self, include_blank=True,
- blank_choice=BLANK_CHOICE_DASH):
- """
- Returns flattened choices with a default blank choice included.
- """
- first_choice = blank_choice if include_blank else []
- return first_choice + list(self.flatchoices)
-
- def _get_val_from_obj(self, obj):
- if obj is not None:
- return getattr(obj, self.attname)
- else:
- return self.get_default()
-
- def value_to_string(self, obj):
- """
- Returns a string value of this field from the passed obj.
- This is used by the serialization framework.
- """
- return smart_text(self._get_val_from_obj(obj))
-
- def bind(self, fieldmapping, original, bound_field_class):
- return bound_field_class(self, fieldmapping, original)
-
- def _get_choices(self):
- if is_iterator(self._choices):
- choices, self._choices = tee(self._choices)
- return choices
- else:
- return self._choices
- choices = property(_get_choices)
-
- def _get_flatchoices(self):
- """Flattened version of choices tuple."""
- flat = []
- for choice, value in self.choices:
- if isinstance(value, (list, tuple)):
- flat.extend(value)
- else:
- flat.append((choice,value))
- return flat
- flatchoices = property(_get_flatchoices)
-
- def save_form_data(self, instance, data):
- setattr(instance, self.name, data)
-
- def formfield(self, form_class=None, choices_form_class=None, **kwargs):
- """
- Returns a django.forms.Field instance for this database Field.
- """
- defaults = {'required': not self.blank,
- 'label': capfirst(self.verbose_name),
- 'help_text': self.help_text}
- if self.has_default():
- if callable(self.default):
- defaults['initial'] = self.default
- defaults['show_hidden_initial'] = True
- else:
- defaults['initial'] = self.get_default()
- if self.choices:
- # Fields with choices get special treatment.
- include_blank = (self.blank or
- not (self.has_default() or 'initial' in kwargs))
- defaults['choices'] = self.get_choices(include_blank=include_blank)
- defaults['coerce'] = self.to_python
- if self.null:
- defaults['empty_value'] = None
- if choices_form_class is not None:
- form_class = choices_form_class
- else:
- form_class = forms.TypedChoiceField
- # Many of the subclass-specific formfield arguments (min_value,
- # max_value) don't apply for choice fields, so be sure to only pass
- # the values that TypedChoiceField will understand.
- for k in list(kwargs):
- if k not in ('coerce', 'empty_value', 'choices', 'required',
- 'widget', 'label', 'initial', 'help_text',
- 'error_messages', 'show_hidden_initial'):
- del kwargs[k]
- defaults.update(kwargs)
- if form_class is None:
- form_class = forms.CharField
- return form_class(**defaults)
-
- def value_from_object(self, obj):
- """
- Returns the value of this field in the given model instance.
- """
- return getattr(obj, self.attname)
-
- def __repr__(self):
- """
- Displays the module, class and name of the field.
- """
- path = '%s.%s' % (self.__class__.__module__, self.__class__.__name__)
- name = getattr(self, 'name', None)
- if name is not None:
- return '<%s: %s>' % (path, name)
- return '<%s>' % path
-
-class AutoField(Field):
- description = _("Integer")
-
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value must be an integer."),
- }
-
- def __init__(self, *args, **kwargs):
- assert kwargs.get('primary_key', False) is True, \
- "%ss must have primary_key=True." % self.__class__.__name__
- kwargs['blank'] = True
- Field.__init__(self, *args, **kwargs)
-
- def get_internal_type(self):
- return "AutoField"
-
- def to_python(self, value):
- if value is None:
- return value
- try:
- return int(value)
- except (TypeError, ValueError):
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def validate(self, value, model_instance):
- pass
-
- def get_db_prep_value(self, value, connection, prepared=False):
- if not prepared:
- value = self.get_prep_value(value)
- value = connection.ops.validate_autopk_value(value)
- return value
-
- def get_prep_value(self, value):
- if value is None:
- return None
- return int(value)
-
- def contribute_to_class(self, cls, name):
- assert not cls._meta.has_auto_field, \
- "A model can't have more than one AutoField."
- super(AutoField, self).contribute_to_class(cls, name)
- cls._meta.has_auto_field = True
- cls._meta.auto_field = self
-
- def formfield(self, **kwargs):
- return None
-
-class BooleanField(Field):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value must be either True or False."),
- }
- description = _("Boolean (Either True or False)")
-
- def __init__(self, *args, **kwargs):
- kwargs['blank'] = True
- Field.__init__(self, *args, **kwargs)
-
- def get_internal_type(self):
- return "BooleanField"
-
- def to_python(self, value):
- if value in (True, False):
- # if value is 1 or 0 than it's equal to True or False, but we want
- # to return a true bool for semantic reasons.
- return bool(value)
- if value in ('t', 'True', '1'):
- return True
- if value in ('f', 'False', '0'):
- return False
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def get_prep_lookup(self, lookup_type, value):
- # Special-case handling for filters coming from a Web request (e.g. the
- # admin interface). Only works for scalar values (not lists). If you're
- # passing in a list, you might as well make things the right type when
- # constructing the list.
- if value in ('1', '0'):
- value = bool(int(value))
- return super(BooleanField, self).get_prep_lookup(lookup_type, value)
-
- def get_prep_value(self, value):
- if value is None:
- return None
- return bool(value)
-
- def formfield(self, **kwargs):
- # Unlike most fields, BooleanField figures out include_blank from
- # self.null instead of self.blank.
- if self.choices:
- include_blank = (self.null or
- not (self.has_default() or 'initial' in kwargs))
- defaults = {'choices': self.get_choices(
- include_blank=include_blank)}
- else:
- defaults = {'form_class': forms.BooleanField}
- defaults.update(kwargs)
- return super(BooleanField, self).formfield(**defaults)
-
-class CharField(Field):
- description = _("String (up to %(max_length)s)")
-
- def __init__(self, *args, **kwargs):
- super(CharField, self).__init__(*args, **kwargs)
- self.validators.append(validators.MaxLengthValidator(self.max_length))
-
- def get_internal_type(self):
- return "CharField"
-
- def to_python(self, value):
- if isinstance(value, six.string_types) or value is None:
- return value
- return smart_text(value)
-
- def get_prep_value(self, value):
- return self.to_python(value)
-
- def formfield(self, **kwargs):
- # Passing max_length to forms.CharField means that the value's length
- # will be validated twice. This is considered acceptable since we want
- # the value in the form field (to pass into widget for example).
- defaults = {'max_length': self.max_length}
- defaults.update(kwargs)
- return super(CharField, self).formfield(**defaults)
-
-# TODO: Maybe move this into contrib, because it's specialized.
-class CommaSeparatedIntegerField(CharField):
- default_validators = [validators.validate_comma_separated_integer_list]
- description = _("Comma-separated integers")
-
- def formfield(self, **kwargs):
- defaults = {
- 'error_messages': {
- 'invalid': _('Enter only digits separated by commas.'),
- }
- }
- defaults.update(kwargs)
- return super(CommaSeparatedIntegerField, self).formfield(**defaults)
-
-class DateField(Field):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value has an invalid date format. It must be "
- "in YYYY-MM-DD format."),
- 'invalid_date': _("'%(value)s' value has the correct format (YYYY-MM-DD) "
- "but it is an invalid date."),
- }
- description = _("Date (without time)")
-
- def __init__(self, verbose_name=None, name=None, auto_now=False,
- auto_now_add=False, **kwargs):
- self.auto_now, self.auto_now_add = auto_now, auto_now_add
- if auto_now or auto_now_add:
- kwargs['editable'] = False
- kwargs['blank'] = True
- Field.__init__(self, verbose_name, name, **kwargs)
-
- def get_internal_type(self):
- return "DateField"
-
- def to_python(self, value):
- if value is None:
- return value
- if isinstance(value, datetime.datetime):
- if settings.USE_TZ and timezone.is_aware(value):
- # Convert aware datetimes to the default time zone
- # before casting them to dates (#17742).
- default_timezone = timezone.get_default_timezone()
- value = timezone.make_naive(value, default_timezone)
- return value.date()
- if isinstance(value, datetime.date):
- return value
-
- try:
- parsed = parse_date(value)
- if parsed is not None:
- return parsed
- except ValueError:
- raise exceptions.ValidationError(
- self.error_messages['invalid_date'],
- code='invalid_date',
- params={'value': value},
- )
-
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def pre_save(self, model_instance, add):
- if self.auto_now or (self.auto_now_add and add):
- value = datetime.date.today()
- setattr(model_instance, self.attname, value)
- return value
- else:
- return super(DateField, self).pre_save(model_instance, add)
-
- def contribute_to_class(self, cls, name):
- super(DateField,self).contribute_to_class(cls, name)
- if not self.null:
- setattr(cls, 'get_next_by_%s' % self.name,
- curry(cls._get_next_or_previous_by_FIELD, field=self,
- is_next=True))
- setattr(cls, 'get_previous_by_%s' % self.name,
- curry(cls._get_next_or_previous_by_FIELD, field=self,
- is_next=False))
-
- def get_prep_lookup(self, lookup_type, value):
- # For dates lookups, convert the value to an int
- # so the database backend always sees a consistent type.
- if lookup_type in ('month', 'day', 'week_day', 'hour', 'minute', 'second'):
- return int(value)
- return super(DateField, self).get_prep_lookup(lookup_type, value)
-
- def get_prep_value(self, value):
- return self.to_python(value)
-
- def get_db_prep_value(self, value, connection, prepared=False):
- # Casts dates into the format expected by the backend
- if not prepared:
- value = self.get_prep_value(value)
- return connection.ops.value_to_db_date(value)
-
- def value_to_string(self, obj):
- val = self._get_val_from_obj(obj)
- return '' if val is None else val.isoformat()
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.DateField}
- defaults.update(kwargs)
- return super(DateField, self).formfield(**defaults)
-
-class DateTimeField(DateField):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value has an invalid format. It must be in "
- "YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."),
- 'invalid_date': _("'%(value)s' value has the correct format "
- "(YYYY-MM-DD) but it is an invalid date."),
- 'invalid_datetime': _("'%(value)s' value has the correct format "
- "(YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) "
- "but it is an invalid date/time."),
- }
- description = _("Date (with time)")
-
- # __init__ is inherited from DateField
-
- def get_internal_type(self):
- return "DateTimeField"
-
- def to_python(self, value):
- if value is None:
- return value
- if isinstance(value, datetime.datetime):
- return value
- if isinstance(value, datetime.date):
- value = datetime.datetime(value.year, value.month, value.day)
- if settings.USE_TZ:
- # For backwards compatibility, interpret naive datetimes in
- # local time. This won't work during DST change, but we can't
- # do much about it, so we let the exceptions percolate up the
- # call stack.
- warnings.warn("DateTimeField %s.%s received a naive datetime "
- "(%s) while time zone support is active." %
- (self.model.__name__, self.name, value),
- RuntimeWarning)
- default_timezone = timezone.get_default_timezone()
- value = timezone.make_aware(value, default_timezone)
- return value
-
- try:
- parsed = parse_datetime(value)
- if parsed is not None:
- return parsed
- except ValueError:
- raise exceptions.ValidationError(
- self.error_messages['invalid_datetime'],
- code='invalid_datetime',
- params={'value': value},
- )
-
- try:
- parsed = parse_date(value)
- if parsed is not None:
- return datetime.datetime(parsed.year, parsed.month, parsed.day)
- except ValueError:
- raise exceptions.ValidationError(
- self.error_messages['invalid_date'],
- code='invalid_date',
- params={'value': value},
- )
-
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def pre_save(self, model_instance, add):
- if self.auto_now or (self.auto_now_add and add):
- value = timezone.now()
- setattr(model_instance, self.attname, value)
- return value
- else:
- return super(DateTimeField, self).pre_save(model_instance, add)
-
- # contribute_to_class is inherited from DateField, it registers
- # get_next_by_FOO and get_prev_by_FOO
-
- # get_prep_lookup is inherited from DateField
-
- def get_prep_value(self, value):
- value = self.to_python(value)
- if value is not None and settings.USE_TZ and timezone.is_naive(value):
- # For backwards compatibility, interpret naive datetimes in local
- # time. This won't work during DST change, but we can't do much
- # about it, so we let the exceptions percolate up the call stack.
- warnings.warn("DateTimeField %s.%s received a naive datetime (%s)"
- " while time zone support is active." %
- (self.model.__name__, self.name, value),
- RuntimeWarning)
- default_timezone = timezone.get_default_timezone()
- value = timezone.make_aware(value, default_timezone)
- return value
-
- def get_db_prep_value(self, value, connection, prepared=False):
- # Casts datetimes into the format expected by the backend
- if not prepared:
- value = self.get_prep_value(value)
- return connection.ops.value_to_db_datetime(value)
-
- def value_to_string(self, obj):
- val = self._get_val_from_obj(obj)
- return '' if val is None else val.isoformat()
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.DateTimeField}
- defaults.update(kwargs)
- return super(DateTimeField, self).formfield(**defaults)
-
-class DecimalField(Field):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value must be a decimal number."),
- }
- description = _("Decimal number")
-
- def __init__(self, verbose_name=None, name=None, max_digits=None,
- decimal_places=None, **kwargs):
- self.max_digits, self.decimal_places = max_digits, decimal_places
- Field.__init__(self, verbose_name, name, **kwargs)
-
- def get_internal_type(self):
- return "DecimalField"
-
- def to_python(self, value):
- if value is None:
- return value
- try:
- return decimal.Decimal(value)
- except decimal.InvalidOperation:
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def _format(self, value):
- if isinstance(value, six.string_types) or value is None:
- return value
- else:
- return self.format_number(value)
-
- def format_number(self, value):
- """
- Formats a number into a string with the requisite number of digits and
- decimal places.
- """
- # Method moved to django.db.backends.util.
- #
- # It is preserved because it is used by the oracle backend
- # (django.db.backends.oracle.query), and also for
- # backwards-compatibility with any external code which may have used
- # this method.
- from django.db.backends import util
- return util.format_number(value, self.max_digits, self.decimal_places)
-
- def get_db_prep_save(self, value, connection):
- return connection.ops.value_to_db_decimal(self.to_python(value),
- self.max_digits, self.decimal_places)
-
- def get_prep_value(self, value):
- return self.to_python(value)
-
- def formfield(self, **kwargs):
- defaults = {
- 'max_digits': self.max_digits,
- 'decimal_places': self.decimal_places,
- 'form_class': forms.DecimalField,
- }
- defaults.update(kwargs)
- return super(DecimalField, self).formfield(**defaults)
-
-class EmailField(CharField):
- default_validators = [validators.validate_email]
- description = _("Email address")
-
- def __init__(self, *args, **kwargs):
- # max_length should be overridden to 254 characters to be fully
- # compliant with RFCs 3696 and 5321
-
- kwargs['max_length'] = kwargs.get('max_length', 75)
- CharField.__init__(self, *args, **kwargs)
-
- def formfield(self, **kwargs):
- # As with CharField, this will cause email validation to be performed
- # twice.
- defaults = {
- 'form_class': forms.EmailField,
- }
- defaults.update(kwargs)
- return super(EmailField, self).formfield(**defaults)
-
-class FilePathField(Field):
- description = _("File path")
-
- def __init__(self, verbose_name=None, name=None, path='', match=None,
- recursive=False, allow_files=True, allow_folders=False, **kwargs):
- self.path, self.match, self.recursive = path, match, recursive
- self.allow_files, self.allow_folders = allow_files, allow_folders
- kwargs['max_length'] = kwargs.get('max_length', 100)
- Field.__init__(self, verbose_name, name, **kwargs)
-
- def get_prep_value(self, value):
- value = super(FilePathField, self).get_prep_value(value)
- if value is None:
- return None
- return six.text_type(value)
-
- def formfield(self, **kwargs):
- defaults = {
- 'path': self.path,
- 'match': self.match,
- 'recursive': self.recursive,
- 'form_class': forms.FilePathField,
- 'allow_files': self.allow_files,
- 'allow_folders': self.allow_folders,
- }
- defaults.update(kwargs)
- return super(FilePathField, self).formfield(**defaults)
-
- def get_internal_type(self):
- return "FilePathField"
-
-class FloatField(Field):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value must be a float."),
- }
- description = _("Floating point number")
-
- def get_prep_value(self, value):
- if value is None:
- return None
- return float(value)
-
- def get_internal_type(self):
- return "FloatField"
-
- def to_python(self, value):
- if value is None:
- return value
- try:
- return float(value)
- except (TypeError, ValueError):
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.FloatField}
- defaults.update(kwargs)
- return super(FloatField, self).formfield(**defaults)
-
-class IntegerField(Field):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value must be an integer."),
- }
- description = _("Integer")
-
- def get_prep_value(self, value):
- if value is None:
- return None
- return int(value)
-
- def get_prep_lookup(self, lookup_type, value):
- if ((lookup_type == 'gte' or lookup_type == 'lt')
- and isinstance(value, float)):
- value = math.ceil(value)
- return super(IntegerField, self).get_prep_lookup(lookup_type, value)
-
- def get_internal_type(self):
- return "IntegerField"
-
- def to_python(self, value):
- if value is None:
- return value
- try:
- return int(value)
- except (TypeError, ValueError):
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.IntegerField}
- defaults.update(kwargs)
- return super(IntegerField, self).formfield(**defaults)
-
-class BigIntegerField(IntegerField):
- empty_strings_allowed = False
- description = _("Big (8 byte) integer")
- MAX_BIGINT = 9223372036854775807
-
- def get_internal_type(self):
- return "BigIntegerField"
-
- def formfield(self, **kwargs):
- defaults = {'min_value': -BigIntegerField.MAX_BIGINT - 1,
- 'max_value': BigIntegerField.MAX_BIGINT}
- defaults.update(kwargs)
- return super(BigIntegerField, self).formfield(**defaults)
-
-class IPAddressField(Field):
- empty_strings_allowed = False
- description = _("IPv4 address")
-
- def __init__(self, *args, **kwargs):
- kwargs['max_length'] = 15
- Field.__init__(self, *args, **kwargs)
-
- def get_prep_value(self, value):
- value = super(IPAddressField, self).get_prep_value(value)
- if value is None:
- return None
- return six.text_type(value)
-
- def get_internal_type(self):
- return "IPAddressField"
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.IPAddressField}
- defaults.update(kwargs)
- return super(IPAddressField, self).formfield(**defaults)
-
-class GenericIPAddressField(Field):
- empty_strings_allowed = True
- description = _("IP address")
- default_error_messages = {}
-
- def __init__(self, verbose_name=None, name=None, protocol='both',
- unpack_ipv4=False, *args, **kwargs):
- self.unpack_ipv4 = unpack_ipv4
- self.protocol = protocol
- self.default_validators, invalid_error_message = \
- validators.ip_address_validators(protocol, unpack_ipv4)
- self.default_error_messages['invalid'] = invalid_error_message
- kwargs['max_length'] = 39
- Field.__init__(self, verbose_name, name, *args, **kwargs)
-
- def get_internal_type(self):
- return "GenericIPAddressField"
-
- def to_python(self, value):
- if value and ':' in value:
- return clean_ipv6_address(value,
- self.unpack_ipv4, self.error_messages['invalid'])
- return value
-
- def get_db_prep_value(self, value, connection, prepared=False):
- if not prepared:
- value = self.get_prep_value(value)
- return value or None
-
- def get_prep_value(self, value):
- if value is None:
- return value
- if value and ':' in value:
- try:
- return clean_ipv6_address(value, self.unpack_ipv4)
- except exceptions.ValidationError:
- pass
- return six.text_type(value)
-
- def formfield(self, **kwargs):
- defaults = {
- 'protocol': self.protocol,
- 'form_class': forms.GenericIPAddressField,
- }
- defaults.update(kwargs)
- return super(GenericIPAddressField, self).formfield(**defaults)
-
-
-class NullBooleanField(Field):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value must be either None, True or False."),
- }
- description = _("Boolean (Either True, False or None)")
-
- def __init__(self, *args, **kwargs):
- kwargs['null'] = True
- kwargs['blank'] = True
- Field.__init__(self, *args, **kwargs)
-
- def get_internal_type(self):
- return "NullBooleanField"
-
- def to_python(self, value):
- if value is None:
- return None
- if value in (True, False):
- return bool(value)
- if value in ('None',):
- return None
- if value in ('t', 'True', '1'):
- return True
- if value in ('f', 'False', '0'):
- return False
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def get_prep_lookup(self, lookup_type, value):
- # Special-case handling for filters coming from a Web request (e.g. the
- # admin interface). Only works for scalar values (not lists). If you're
- # passing in a list, you might as well make things the right type when
- # constructing the list.
- if value in ('1', '0'):
- value = bool(int(value))
- return super(NullBooleanField, self).get_prep_lookup(lookup_type,
- value)
-
- def get_prep_value(self, value):
- if value is None:
- return None
- return bool(value)
-
- def formfield(self, **kwargs):
- defaults = {
- 'form_class': forms.NullBooleanField,
- 'required': not self.blank,
- 'label': capfirst(self.verbose_name),
- 'help_text': self.help_text}
- defaults.update(kwargs)
- return super(NullBooleanField, self).formfield(**defaults)
-
-class PositiveIntegerField(IntegerField):
- description = _("Positive integer")
-
- def get_internal_type(self):
- return "PositiveIntegerField"
-
- def formfield(self, **kwargs):
- defaults = {'min_value': 0}
- defaults.update(kwargs)
- return super(PositiveIntegerField, self).formfield(**defaults)
-
-class PositiveSmallIntegerField(IntegerField):
- description = _("Positive small integer")
-
- def get_internal_type(self):
- return "PositiveSmallIntegerField"
-
- def formfield(self, **kwargs):
- defaults = {'min_value': 0}
- defaults.update(kwargs)
- return super(PositiveSmallIntegerField, self).formfield(**defaults)
-
-class SlugField(CharField):
- default_validators = [validators.validate_slug]
- description = _("Slug (up to %(max_length)s)")
-
- def __init__(self, *args, **kwargs):
- kwargs['max_length'] = kwargs.get('max_length', 50)
- # Set db_index=True unless it's been set manually.
- if 'db_index' not in kwargs:
- kwargs['db_index'] = True
- super(SlugField, self).__init__(*args, **kwargs)
-
- def get_internal_type(self):
- return "SlugField"
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.SlugField}
- defaults.update(kwargs)
- return super(SlugField, self).formfield(**defaults)
-
-class SmallIntegerField(IntegerField):
- description = _("Small integer")
-
- def get_internal_type(self):
- return "SmallIntegerField"
-
-class TextField(Field):
- description = _("Text")
-
- def get_internal_type(self):
- return "TextField"
-
- def get_prep_value(self, value):
- if isinstance(value, six.string_types) or value is None:
- return value
- return smart_text(value)
-
- def formfield(self, **kwargs):
- defaults = {'widget': forms.Textarea}
- defaults.update(kwargs)
- return super(TextField, self).formfield(**defaults)
-
-class TimeField(Field):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _("'%(value)s' value has an invalid format. It must be in "
- "HH:MM[:ss[.uuuuuu]] format."),
- 'invalid_time': _("'%(value)s' value has the correct format "
- "(HH:MM[:ss[.uuuuuu]]) but it is an invalid time."),
- }
- description = _("Time")
-
- def __init__(self, verbose_name=None, name=None, auto_now=False,
- auto_now_add=False, **kwargs):
- self.auto_now, self.auto_now_add = auto_now, auto_now_add
- if auto_now or auto_now_add:
- kwargs['editable'] = False
- kwargs['blank'] = True
- Field.__init__(self, verbose_name, name, **kwargs)
-
- def get_internal_type(self):
- return "TimeField"
-
- def to_python(self, value):
- if value is None:
- return None
- if isinstance(value, datetime.time):
- return value
- if isinstance(value, datetime.datetime):
- # Not usually a good idea to pass in a datetime here (it loses
- # information), but this can be a side-effect of interacting with a
- # database backend (e.g. Oracle), so we'll be accommodating.
- return value.time()
-
- try:
- parsed = parse_time(value)
- if parsed is not None:
- return parsed
- except ValueError:
- raise exceptions.ValidationError(
- self.error_messages['invalid_time'],
- code='invalid_time',
- params={'value': value},
- )
-
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'value': value},
- )
-
- def pre_save(self, model_instance, add):
- if self.auto_now or (self.auto_now_add and add):
- value = datetime.datetime.now().time()
- setattr(model_instance, self.attname, value)
- return value
- else:
- return super(TimeField, self).pre_save(model_instance, add)
-
- def get_prep_value(self, value):
- return self.to_python(value)
-
- def get_db_prep_value(self, value, connection, prepared=False):
- # Casts times into the format expected by the backend
- if not prepared:
- value = self.get_prep_value(value)
- return connection.ops.value_to_db_time(value)
-
- def value_to_string(self, obj):
- val = self._get_val_from_obj(obj)
- return '' if val is None else val.isoformat()
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.TimeField}
- defaults.update(kwargs)
- return super(TimeField, self).formfield(**defaults)
-
-class URLField(CharField):
- default_validators = [validators.URLValidator()]
- description = _("URL")
-
- def __init__(self, verbose_name=None, name=None, **kwargs):
- kwargs['max_length'] = kwargs.get('max_length', 200)
- CharField.__init__(self, verbose_name, name, **kwargs)
-
- def formfield(self, **kwargs):
- # As with CharField, this will cause URL validation to be performed
- # twice.
- defaults = {
- 'form_class': forms.URLField,
- }
- defaults.update(kwargs)
- return super(URLField, self).formfield(**defaults)
-
-class BinaryField(Field):
- description = _("Raw binary data")
- empty_values = [None, b'']
-
- def __init__(self, *args, **kwargs):
- kwargs['editable'] = False
- super(BinaryField, self).__init__(*args, **kwargs)
- if self.max_length is not None:
- self.validators.append(validators.MaxLengthValidator(self.max_length))
-
- def get_internal_type(self):
- return "BinaryField"
-
- def get_default(self):
- if self.has_default() and not callable(self.default):
- return self.default
- default = super(BinaryField, self).get_default()
- if default == '':
- return b''
- return default
-
- def get_db_prep_value(self, value, connection, prepared=False):
- value = super(BinaryField, self
- ).get_db_prep_value(value, connection, prepared)
- if value is not None:
- return connection.Database.Binary(value)
- return value
-
- def value_to_string(self, obj):
- """Binary data is serialized as base64"""
- return b64encode(force_bytes(self._get_val_from_obj(obj))).decode('ascii')
-
- def to_python(self, value):
- # If it's a string, it should be base64-encoded data
- if isinstance(value, six.text_type):
- return six.memoryview(b64decode(force_bytes(value)))
- return value
diff --git a/lib/python2.7/site-packages/django/db/models/fields/files.py b/lib/python2.7/site-packages/django/db/models/fields/files.py
deleted file mode 100644
index 3b3c1ec..0000000
--- a/lib/python2.7/site-packages/django/db/models/fields/files.py
+++ /dev/null
@@ -1,397 +0,0 @@
-import datetime
-import os
-
-from django import forms
-from django.db.models.fields import Field
-from django.core.files.base import File
-from django.core.files.storage import default_storage
-from django.core.files.images import ImageFile
-from django.db.models import signals
-from django.utils.encoding import force_str, force_text
-from django.utils import six
-from django.utils.translation import ugettext_lazy as _
-
-class FieldFile(File):
- def __init__(self, instance, field, name):
- super(FieldFile, self).__init__(None, name)
- self.instance = instance
- self.field = field
- self.storage = field.storage
- self._committed = True
-
- def __eq__(self, other):
- # Older code may be expecting FileField values to be simple strings.
- # By overriding the == operator, it can remain backwards compatibility.
- if hasattr(other, 'name'):
- return self.name == other.name
- return self.name == other
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __hash__(self):
- return hash(self.name)
-
- # The standard File contains most of the necessary properties, but
- # FieldFiles can be instantiated without a name, so that needs to
- # be checked for here.
-
- def _require_file(self):
- if not self:
- raise ValueError("The '%s' attribute has no file associated with it." % self.field.name)
-
- def _get_file(self):
- self._require_file()
- if not hasattr(self, '_file') or self._file is None:
- self._file = self.storage.open(self.name, 'rb')
- return self._file
-
- def _set_file(self, file):
- self._file = file
-
- def _del_file(self):
- del self._file
-
- file = property(_get_file, _set_file, _del_file)
-
- def _get_path(self):
- self._require_file()
- return self.storage.path(self.name)
- path = property(_get_path)
-
- def _get_url(self):
- self._require_file()
- return self.storage.url(self.name)
- url = property(_get_url)
-
- def _get_size(self):
- self._require_file()
- if not self._committed:
- return self.file.size
- return self.storage.size(self.name)
- size = property(_get_size)
-
- def open(self, mode='rb'):
- self._require_file()
- self.file.open(mode)
- # open() doesn't alter the file's contents, but it does reset the pointer
- open.alters_data = True
-
- # In addition to the standard File API, FieldFiles have extra methods
- # to further manipulate the underlying file, as well as update the
- # associated model instance.
-
- def save(self, name, content, save=True):
- name = self.field.generate_filename(self.instance, name)
- self.name = self.storage.save(name, content)
- setattr(self.instance, self.field.name, self.name)
-
- # Update the filesize cache
- self._size = content.size
- self._committed = True
-
- # Save the object because it has changed, unless save is False
- if save:
- self.instance.save()
- save.alters_data = True
-
- def delete(self, save=True):
- if not self:
- return
- # Only close the file if it's already open, which we know by the
- # presence of self._file
- if hasattr(self, '_file'):
- self.close()
- del self.file
-
- self.storage.delete(self.name)
-
- self.name = None
- setattr(self.instance, self.field.name, self.name)
-
- # Delete the filesize cache
- if hasattr(self, '_size'):
- del self._size
- self._committed = False
-
- if save:
- self.instance.save()
- delete.alters_data = True
-
- def _get_closed(self):
- file = getattr(self, '_file', None)
- return file is None or file.closed
- closed = property(_get_closed)
-
- def close(self):
- file = getattr(self, '_file', None)
- if file is not None:
- file.close()
-
- def __getstate__(self):
- # FieldFile needs access to its associated model field and an instance
- # it's attached to in order to work properly, but the only necessary
- # data to be pickled is the file's name itself. Everything else will
- # be restored later, by FileDescriptor below.
- return {'name': self.name, 'closed': False, '_committed': True, '_file': None}
-
-class FileDescriptor(object):
- """
- The descriptor for the file attribute on the model instance. Returns a
- FieldFile when accessed so you can do stuff like::
-
- >>> instance.file.size
-
- Assigns a file object on assignment so you can do::
-
- >>> instance.file = File(...)
-
- """
- def __init__(self, field):
- self.field = field
-
- def __get__(self, instance=None, owner=None):
- if instance is None:
- raise AttributeError(
- "The '%s' attribute can only be accessed from %s instances."
- % (self.field.name, owner.__name__))
-
- # This is slightly complicated, so worth an explanation.
- # instance.file`needs to ultimately return some instance of `File`,
- # probably a subclass. Additionally, this returned object needs to have
- # the FieldFile API so that users can easily do things like
- # instance.file.path and have that delegated to the file storage engine.
- # Easy enough if we're strict about assignment in __set__, but if you
- # peek below you can see that we're not. So depending on the current
- # value of the field we have to dynamically construct some sort of
- # "thing" to return.
-
- # The instance dict contains whatever was originally assigned
- # in __set__.
- file = instance.__dict__[self.field.name]
-
- # If this value is a string (instance.file = "path/to/file") or None
- # then we simply wrap it with the appropriate attribute class according
- # to the file field. [This is FieldFile for FileFields and
- # ImageFieldFile for ImageFields; it's also conceivable that user
- # subclasses might also want to subclass the attribute class]. This
- # object understands how to convert a path to a file, and also how to
- # handle None.
- if isinstance(file, six.string_types) or file is None:
- attr = self.field.attr_class(instance, self.field, file)
- instance.__dict__[self.field.name] = attr
-
- # Other types of files may be assigned as well, but they need to have
- # the FieldFile interface added to the. Thus, we wrap any other type of
- # File inside a FieldFile (well, the field's attr_class, which is
- # usually FieldFile).
- elif isinstance(file, File) and not isinstance(file, FieldFile):
- file_copy = self.field.attr_class(instance, self.field, file.name)
- file_copy.file = file
- file_copy._committed = False
- instance.__dict__[self.field.name] = file_copy
-
- # Finally, because of the (some would say boneheaded) way pickle works,
- # the underlying FieldFile might not actually itself have an associated
- # file. So we need to reset the details of the FieldFile in those cases.
- elif isinstance(file, FieldFile) and not hasattr(file, 'field'):
- file.instance = instance
- file.field = self.field
- file.storage = self.field.storage
-
- # That was fun, wasn't it?
- return instance.__dict__[self.field.name]
-
- def __set__(self, instance, value):
- instance.__dict__[self.field.name] = value
-
-class FileField(Field):
-
- # The class to wrap instance attributes in. Accessing the file object off
- # the instance will always return an instance of attr_class.
- attr_class = FieldFile
-
- # The descriptor to use for accessing the attribute off of the class.
- descriptor_class = FileDescriptor
-
- description = _("File")
-
- def __init__(self, verbose_name=None, name=None, upload_to='', storage=None, **kwargs):
- for arg in ('primary_key', 'unique'):
- if arg in kwargs:
- raise TypeError("'%s' is not a valid argument for %s." % (arg, self.__class__))
-
- self.storage = storage or default_storage
- self.upload_to = upload_to
- if callable(upload_to):
- self.generate_filename = upload_to
-
- kwargs['max_length'] = kwargs.get('max_length', 100)
- super(FileField, self).__init__(verbose_name, name, **kwargs)
-
- def get_internal_type(self):
- return "FileField"
-
- def get_prep_lookup(self, lookup_type, value):
- if hasattr(value, 'name'):
- value = value.name
- return super(FileField, self).get_prep_lookup(lookup_type, value)
-
- def get_prep_value(self, value):
- "Returns field's value prepared for saving into a database."
- # Need to convert File objects provided via a form to unicode for database insertion
- if value is None:
- return None
- return six.text_type(value)
-
- def pre_save(self, model_instance, add):
- "Returns field's value just before saving."
- file = super(FileField, self).pre_save(model_instance, add)
- if file and not file._committed:
- # Commit the file to storage prior to saving the model
- file.save(file.name, file, save=False)
- return file
-
- def contribute_to_class(self, cls, name):
- super(FileField, self).contribute_to_class(cls, name)
- setattr(cls, self.name, self.descriptor_class(self))
-
- def get_directory_name(self):
- return os.path.normpath(force_text(datetime.datetime.now().strftime(force_str(self.upload_to))))
-
- def get_filename(self, filename):
- return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))
-
- def generate_filename(self, instance, filename):
- return os.path.join(self.get_directory_name(), self.get_filename(filename))
-
- def save_form_data(self, instance, data):
- # Important: None means "no change", other false value means "clear"
- # This subtle distinction (rather than a more explicit marker) is
- # needed because we need to consume values that are also sane for a
- # regular (non Model-) Form to find in its cleaned_data dictionary.
- if data is not None:
- # This value will be converted to unicode and stored in the
- # database, so leaving False as-is is not acceptable.
- if not data:
- data = ''
- setattr(instance, self.name, data)
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.FileField, 'max_length': self.max_length}
- # If a file has been provided previously, then the form doesn't require
- # that a new file is provided this time.
- # The code to mark the form field as not required is used by
- # form_for_instance, but can probably be removed once form_for_instance
- # is gone. ModelForm uses a different method to check for an existing file.
- if 'initial' in kwargs:
- defaults['required'] = False
- defaults.update(kwargs)
- return super(FileField, self).formfield(**defaults)
-
-class ImageFileDescriptor(FileDescriptor):
- """
- Just like the FileDescriptor, but for ImageFields. The only difference is
- assigning the width/height to the width_field/height_field, if appropriate.
- """
- def __set__(self, instance, value):
- previous_file = instance.__dict__.get(self.field.name)
- super(ImageFileDescriptor, self).__set__(instance, value)
-
- # To prevent recalculating image dimensions when we are instantiating
- # an object from the database (bug #11084), only update dimensions if
- # the field had a value before this assignment. Since the default
- # value for FileField subclasses is an instance of field.attr_class,
- # previous_file will only be None when we are called from
- # Model.__init__(). The ImageField.update_dimension_fields method
- # hooked up to the post_init signal handles the Model.__init__() cases.
- # Assignment happening outside of Model.__init__() will trigger the
- # update right here.
- if previous_file is not None:
- self.field.update_dimension_fields(instance, force=True)
-
-class ImageFieldFile(ImageFile, FieldFile):
-
- def delete(self, save=True):
- # Clear the image dimensions cache
- if hasattr(self, '_dimensions_cache'):
- del self._dimensions_cache
- super(ImageFieldFile, self).delete(save)
-
-class ImageField(FileField):
- attr_class = ImageFieldFile
- descriptor_class = ImageFileDescriptor
- description = _("Image")
-
- def __init__(self, verbose_name=None, name=None, width_field=None,
- height_field=None, **kwargs):
- self.width_field, self.height_field = width_field, height_field
- super(ImageField, self).__init__(verbose_name, name, **kwargs)
-
- def contribute_to_class(self, cls, name):
- super(ImageField, self).contribute_to_class(cls, name)
- # Attach update_dimension_fields so that dimension fields declared
- # after their corresponding image field don't stay cleared by
- # Model.__init__, see bug #11196.
- signals.post_init.connect(self.update_dimension_fields, sender=cls)
-
- def update_dimension_fields(self, instance, force=False, *args, **kwargs):
- """
- Updates field's width and height fields, if defined.
-
- This method is hooked up to model's post_init signal to update
- dimensions after instantiating a model instance. However, dimensions
- won't be updated if the dimensions fields are already populated. This
- avoids unnecessary recalculation when loading an object from the
- database.
-
- Dimensions can be forced to update with force=True, which is how
- ImageFileDescriptor.__set__ calls this method.
- """
- # Nothing to update if the field doesn't have have dimension fields.
- has_dimension_fields = self.width_field or self.height_field
- if not has_dimension_fields:
- return
-
- # getattr will call the ImageFileDescriptor's __get__ method, which
- # coerces the assigned value into an instance of self.attr_class
- # (ImageFieldFile in this case).
- file = getattr(instance, self.attname)
-
- # Nothing to update if we have no file and not being forced to update.
- if not file and not force:
- return
-
- dimension_fields_filled = not(
- (self.width_field and not getattr(instance, self.width_field))
- or (self.height_field and not getattr(instance, self.height_field))
- )
- # When both dimension fields have values, we are most likely loading
- # data from the database or updating an image field that already had
- # an image stored. In the first case, we don't want to update the
- # dimension fields because we are already getting their values from the
- # database. In the second case, we do want to update the dimensions
- # fields and will skip this return because force will be True since we
- # were called from ImageFileDescriptor.__set__.
- if dimension_fields_filled and not force:
- return
-
- # file should be an instance of ImageFieldFile or should be None.
- if file:
- width = file.width
- height = file.height
- else:
- # No file, so clear dimensions fields.
- width = None
- height = None
-
- # Update the width and height fields.
- if self.width_field:
- setattr(instance, self.width_field, width)
- if self.height_field:
- setattr(instance, self.height_field, height)
-
- def formfield(self, **kwargs):
- defaults = {'form_class': forms.ImageField}
- defaults.update(kwargs)
- return super(ImageField, self).formfield(**defaults)
diff --git a/lib/python2.7/site-packages/django/db/models/fields/proxy.py b/lib/python2.7/site-packages/django/db/models/fields/proxy.py
deleted file mode 100644
index c0cc873..0000000
--- a/lib/python2.7/site-packages/django/db/models/fields/proxy.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""
-Field-like classes that aren't really fields. It's easier to use objects that
-have the same attributes as fields sometimes (avoids a lot of special casing).
-"""
-
-from django.db.models import fields
-
-class OrderWrt(fields.IntegerField):
- """
- A proxy for the _order database field that is used when
- Meta.order_with_respect_to is specified.
- """
-
- def __init__(self, *args, **kwargs):
- kwargs['name'] = '_order'
- kwargs['editable'] = False
- super(OrderWrt, self).__init__(*args, **kwargs)
diff --git a/lib/python2.7/site-packages/django/db/models/fields/related.py b/lib/python2.7/site-packages/django/db/models/fields/related.py
deleted file mode 100644
index a4bc374..0000000
--- a/lib/python2.7/site-packages/django/db/models/fields/related.py
+++ /dev/null
@@ -1,1545 +0,0 @@
-from operator import attrgetter
-
-from django.db import connection, connections, router
-from django.db.backends import util
-from django.db.models import signals, get_model
-from django.db.models.fields import (AutoField, Field, IntegerField,
- PositiveIntegerField, PositiveSmallIntegerField, FieldDoesNotExist)
-from django.db.models.related import RelatedObject, PathInfo
-from django.db.models.query import QuerySet
-from django.db.models.deletion import CASCADE
-from django.utils.encoding import smart_text
-from django.utils import six
-from django.utils.deprecation import RenameMethodsBase
-from django.utils.translation import ugettext_lazy as _
-from django.utils.functional import curry, cached_property
-from django.core import exceptions
-from django import forms
-
-RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
-
-pending_lookups = {}
-
-
-def add_lazy_relation(cls, field, relation, operation):
- """
- Adds a lookup on ``cls`` when a related field is defined using a string,
- i.e.::
-
- class MyModel(Model):
- fk = ForeignKey("AnotherModel")
-
- This string can be:
-
- * RECURSIVE_RELATIONSHIP_CONSTANT (i.e. "self") to indicate a recursive
- relation.
-
- * The name of a model (i.e "AnotherModel") to indicate another model in
- the same app.
-
- * An app-label and model name (i.e. "someapp.AnotherModel") to indicate
- another model in a different app.
-
- If the other model hasn't yet been loaded -- almost a given if you're using
- lazy relationships -- then the relation won't be set up until the
- class_prepared signal fires at the end of model initialization.
-
- operation is the work that must be performed once the relation can be resolved.
- """
- # Check for recursive relations
- if relation == RECURSIVE_RELATIONSHIP_CONSTANT:
- app_label = cls._meta.app_label
- model_name = cls.__name__
-
- else:
- # Look for an "app.Model" relation
-
- if isinstance(relation, six.string_types):
- try:
- app_label, model_name = relation.split(".")
- except ValueError:
- # If we can't split, assume a model in current app
- app_label = cls._meta.app_label
- model_name = relation
- else:
- # it's actually a model class
- app_label = relation._meta.app_label
- model_name = relation._meta.object_name
-
- # Try to look up the related model, and if it's already loaded resolve the
- # string right away. If get_model returns None, it means that the related
- # model isn't loaded yet, so we need to pend the relation until the class
- # is prepared.
- model = get_model(app_label, model_name,
- seed_cache=False, only_installed=False)
- if model:
- operation(field, model, cls)
- else:
- key = (app_label, model_name)
- value = (cls, field, operation)
- pending_lookups.setdefault(key, []).append(value)
-
-
-def do_pending_lookups(sender, **kwargs):
- """
- Handle any pending relations to the sending model. Sent from class_prepared.
- """
- key = (sender._meta.app_label, sender.__name__)
- for cls, field, operation in pending_lookups.pop(key, []):
- operation(field, sender, cls)
-
-signals.class_prepared.connect(do_pending_lookups)
-
-
-#HACK
-class RelatedField(Field):
- def db_type(self, connection):
- '''By default related field will not have a column
- as it relates columns to another table'''
- return None
-
- def contribute_to_class(self, cls, name, virtual_only=False):
- sup = super(RelatedField, self)
-
- # Store the opts for related_query_name()
- self.opts = cls._meta
-
- if hasattr(sup, 'contribute_to_class'):
- sup.contribute_to_class(cls, name, virtual_only=virtual_only)
-
- if not cls._meta.abstract and self.rel.related_name:
- related_name = self.rel.related_name % {
- 'class': cls.__name__.lower(),
- 'app_label': cls._meta.app_label.lower()
- }
- self.rel.related_name = related_name
- other = self.rel.to
- if isinstance(other, six.string_types) or other._meta.pk is None:
- def resolve_related_class(field, model, cls):
- field.rel.to = model
- field.do_related_class(model, cls)
- add_lazy_relation(cls, self, other, resolve_related_class)
- else:
- self.do_related_class(other, cls)
-
- def set_attributes_from_rel(self):
- self.name = self.name or (self.rel.to._meta.model_name + '_' + self.rel.to._meta.pk.name)
- if self.verbose_name is None:
- self.verbose_name = self.rel.to._meta.verbose_name
- self.rel.set_field_name()
-
- def do_related_class(self, other, cls):
- self.set_attributes_from_rel()
- self.related = RelatedObject(other, cls, self)
- if not cls._meta.abstract:
- self.contribute_to_related_class(other, self.related)
-
- def related_query_name(self):
- # This method defines the name that can be used to identify this
- # related object in a table-spanning query. It uses the lower-cased
- # object_name by default, but this can be overridden with the
- # "related_name" option.
- return self.rel.related_query_name or self.rel.related_name or self.opts.model_name
-
-
-class RenameRelatedObjectDescriptorMethods(RenameMethodsBase):
- renamed_methods = (
- ('get_query_set', 'get_queryset', PendingDeprecationWarning),
- ('get_prefetch_query_set', 'get_prefetch_queryset', PendingDeprecationWarning),
- )
-
-
-class SingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjectDescriptorMethods)):
- # This class provides the functionality that makes the related-object
- # managers available as attributes on a model class, for fields that have
- # a single "remote" value, on the class pointed to by a related field.
- # In the example "place.restaurant", the restaurant attribute is a
- # SingleRelatedObjectDescriptor instance.
- def __init__(self, related):
- self.related = related
- self.cache_name = related.get_cache_name()
-
- def is_cached(self, instance):
- return hasattr(instance, self.cache_name)
-
- def get_queryset(self, **db_hints):
- db = router.db_for_read(self.related.model, **db_hints)
- return self.related.model._base_manager.using(db)
-
- def get_prefetch_queryset(self, instances):
- rel_obj_attr = attrgetter(self.related.field.attname)
- instance_attr = lambda obj: obj._get_pk_val()
- instances_dict = dict((instance_attr(inst), inst) for inst in instances)
- query = {'%s__in' % self.related.field.name: instances}
- qs = self.get_queryset(instance=instances[0]).filter(**query)
- # Since we're going to assign directly in the cache,
- # we must manage the reverse relation cache manually.
- rel_obj_cache_name = self.related.field.get_cache_name()
- for rel_obj in qs:
- instance = instances_dict[rel_obj_attr(rel_obj)]
- setattr(rel_obj, rel_obj_cache_name, instance)
- return qs, rel_obj_attr, instance_attr, True, self.cache_name
-
- def __get__(self, instance, instance_type=None):
- if instance is None:
- return self
- try:
- rel_obj = getattr(instance, self.cache_name)
- except AttributeError:
- related_pk = instance._get_pk_val()
- if related_pk is None:
- rel_obj = None
- else:
- params = {}
- for lh_field, rh_field in self.related.field.related_fields:
- params['%s__%s' % (self.related.field.name, rh_field.name)] = getattr(instance, rh_field.attname)
- try:
- rel_obj = self.get_queryset(instance=instance).get(**params)
- except self.related.model.DoesNotExist:
- rel_obj = None
- else:
- setattr(rel_obj, self.related.field.get_cache_name(), instance)
- setattr(instance, self.cache_name, rel_obj)
- if rel_obj is None:
- raise self.related.model.DoesNotExist("%s has no %s." % (
- instance.__class__.__name__,
- self.related.get_accessor_name()))
- else:
- return rel_obj
-
- def __set__(self, instance, value):
- # The similarity of the code below to the code in
- # ReverseSingleRelatedObjectDescriptor is annoying, but there's a bunch
- # of small differences that would make a common base class convoluted.
-
- # If null=True, we can assign null here, but otherwise the value needs
- # to be an instance of the related class.
- if value is None and self.related.field.null == False:
- raise ValueError('Cannot assign None: "%s.%s" does not allow null values.' %
- (instance._meta.object_name, self.related.get_accessor_name()))
- elif value is not None and not isinstance(value, self.related.model):
- raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' %
- (value, instance._meta.object_name,
- self.related.get_accessor_name(), self.related.opts.object_name))
- elif value is not None:
- if instance._state.db is None:
- instance._state.db = router.db_for_write(instance.__class__, instance=value)
- elif value._state.db is None:
- value._state.db = router.db_for_write(value.__class__, instance=instance)
- elif value._state.db is not None and instance._state.db is not None:
- if not router.allow_relation(value, instance):
- raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value)
-
- related_pk = tuple([getattr(instance, field.attname) for field in self.related.field.foreign_related_fields])
- if None in related_pk:
- raise ValueError('Cannot assign "%r": "%s" instance isn\'t saved in the database.' %
- (value, instance._meta.object_name))
-
- # Set the value of the related field to the value of the related object's related field
- for index, field in enumerate(self.related.field.local_related_fields):
- setattr(value, field.attname, related_pk[index])
-
- # Since we already know what the related object is, seed the related
- # object caches now, too. This avoids another db hit if you get the
- # object you just set.
- setattr(instance, self.cache_name, value)
- setattr(value, self.related.field.get_cache_name(), instance)
-
-
-class ReverseSingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjectDescriptorMethods)):
- # This class provides the functionality that makes the related-object
- # managers available as attributes on a model class, for fields that have
- # a single "remote" value, on the class that defines the related field.
- # In the example "choice.poll", the poll attribute is a
- # ReverseSingleRelatedObjectDescriptor instance.
- def __init__(self, field_with_rel):
- self.field = field_with_rel
- self.cache_name = self.field.get_cache_name()
-
- def is_cached(self, instance):
- return hasattr(instance, self.cache_name)
-
- def get_queryset(self, **db_hints):
- db = router.db_for_read(self.field.rel.to, **db_hints)
- rel_mgr = self.field.rel.to._default_manager
- # If the related manager indicates that it should be used for
- # related fields, respect that.
- if getattr(rel_mgr, 'use_for_related_fields', False):
- return rel_mgr.using(db)
- else:
- return QuerySet(self.field.rel.to).using(db)
-
- def get_prefetch_queryset(self, instances):
- rel_obj_attr = self.field.get_foreign_related_value
- instance_attr = self.field.get_local_related_value
- instances_dict = dict((instance_attr(inst), inst) for inst in instances)
- related_field = self.field.foreign_related_fields[0]
-
- # FIXME: This will need to be revisited when we introduce support for
- # composite fields. In the meantime we take this practical approach to
- # solve a regression on 1.6 when the reverse manager in hidden
- # (related_name ends with a '+'). Refs #21410.
- # The check for len(...) == 1 is a special case that allows the query
- # to be join-less and smaller. Refs #21760.
- if self.field.rel.is_hidden() or len(self.field.foreign_related_fields) == 1:
- query = {'%s__in' % related_field.name: set(instance_attr(inst)[0] for inst in instances)}
- else:
- query = {'%s__in' % self.field.related_query_name(): instances}
-
- qs = self.get_queryset(instance=instances[0]).filter(**query)
- # Since we're going to assign directly in the cache,
- # we must manage the reverse relation cache manually.
- if not self.field.rel.multiple:
- rel_obj_cache_name = self.field.related.get_cache_name()
- for rel_obj in qs:
- instance = instances_dict[rel_obj_attr(rel_obj)]
- setattr(rel_obj, rel_obj_cache_name, instance)
- return qs, rel_obj_attr, instance_attr, True, self.cache_name
-
- def __get__(self, instance, instance_type=None):
- if instance is None:
- return self
- try:
- rel_obj = getattr(instance, self.cache_name)
- except AttributeError:
- val = self.field.get_local_related_value(instance)
- if None in val:
- rel_obj = None
- else:
- params = dict(
- (rh_field.attname, getattr(instance, lh_field.attname))
- for lh_field, rh_field in self.field.related_fields)
- qs = self.get_queryset(instance=instance)
- extra_filter = self.field.get_extra_descriptor_filter(instance)
- if isinstance(extra_filter, dict):
- params.update(extra_filter)
- qs = qs.filter(**params)
- else:
- qs = qs.filter(extra_filter, **params)
- # Assuming the database enforces foreign keys, this won't fail.
- rel_obj = qs.get()
- if not self.field.rel.multiple:
- setattr(rel_obj, self.field.related.get_cache_name(), instance)
- setattr(instance, self.cache_name, rel_obj)
- if rel_obj is None and not self.field.null:
- raise self.field.rel.to.DoesNotExist(
- "%s has no %s." % (self.field.model.__name__, self.field.name))
- else:
- return rel_obj
-
- def __set__(self, instance, value):
- # If null=True, we can assign null here, but otherwise the value needs
- # to be an instance of the related class.
- if value is None and self.field.null == False:
- raise ValueError('Cannot assign None: "%s.%s" does not allow null values.' %
- (instance._meta.object_name, self.field.name))
- elif value is not None and not isinstance(value, self.field.rel.to):
- raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' %
- (value, instance._meta.object_name,
- self.field.name, self.field.rel.to._meta.object_name))
- elif value is not None:
- if instance._state.db is None:
- instance._state.db = router.db_for_write(instance.__class__, instance=value)
- elif value._state.db is None:
- value._state.db = router.db_for_write(value.__class__, instance=instance)
- elif value._state.db is not None and instance._state.db is not None:
- if not router.allow_relation(value, instance):
- raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value)
-
- # If we're setting the value of a OneToOneField to None, we need to clear
- # out the cache on any old related object. Otherwise, deleting the
- # previously-related object will also cause this object to be deleted,
- # which is wrong.
- if value is None:
- # Look up the previously-related object, which may still be available
- # since we've not yet cleared out the related field.
- # Use the cache directly, instead of the accessor; if we haven't
- # populated the cache, then we don't care - we're only accessing
- # the object to invalidate the accessor cache, so there's no
- # need to populate the cache just to expire it again.
- related = getattr(instance, self.cache_name, None)
-
- # If we've got an old related object, we need to clear out its
- # cache. This cache also might not exist if the related object
- # hasn't been accessed yet.
- if related is not None:
- setattr(related, self.field.related.get_cache_name(), None)
-
- # Set the value of the related field
- for lh_field, rh_field in self.field.related_fields:
- try:
- setattr(instance, lh_field.attname, getattr(value, rh_field.attname))
- except AttributeError:
- setattr(instance, lh_field.attname, None)
-
- # Since we already know what the related object is, seed the related
- # object caches now, too. This avoids another db hit if you get the
- # object you just set.
- setattr(instance, self.cache_name, value)
- if value is not None and not self.field.rel.multiple:
- setattr(value, self.field.related.get_cache_name(), instance)
-
-
-class ForeignRelatedObjectsDescriptor(object):
- # This class provides the functionality that makes the related-object
- # managers available as attributes on a model class, for fields that have
- # multiple "remote" values and have a ForeignKey pointed at them by
- # some other model. In the example "poll.choice_set", the choice_set
- # attribute is a ForeignRelatedObjectsDescriptor instance.
- def __init__(self, related):
- self.related = related # RelatedObject instance
-
- def __get__(self, instance, instance_type=None):
- if instance is None:
- return self
-
- return self.related_manager_cls(instance)
-
- def __set__(self, instance, value):
- manager = self.__get__(instance)
- # If the foreign key can support nulls, then completely clear the related set.
- # Otherwise, just move the named objects into the set.
- if self.related.field.null:
- manager.clear()
- manager.add(*value)
-
- @cached_property
- def related_manager_cls(self):
- # Dynamically create a class that subclasses the related model's default
- # manager.
- superclass = self.related.model._default_manager.__class__
- rel_field = self.related.field
- rel_model = self.related.model
-
- class RelatedManager(superclass):
- def __init__(self, instance):
- super(RelatedManager, self).__init__()
- self.instance = instance
- self.core_filters= {'%s__exact' % rel_field.name: instance}
- self.model = rel_model
-
- def get_queryset(self):
- try:
- return self.instance._prefetched_objects_cache[rel_field.related_query_name()]
- except (AttributeError, KeyError):
- db = self._db or router.db_for_read(self.model, instance=self.instance)
- qs = super(RelatedManager, self).get_queryset().using(db).filter(**self.core_filters)
- empty_strings_as_null = connections[db].features.interprets_empty_strings_as_nulls
- for field in rel_field.foreign_related_fields:
- val = getattr(self.instance, field.attname)
- if val is None or (val == '' and empty_strings_as_null):
- return qs.none()
- qs._known_related_objects = {rel_field: {self.instance.pk: self.instance}}
- return qs
-
- def get_prefetch_queryset(self, instances):
- rel_obj_attr = rel_field.get_local_related_value
- instance_attr = rel_field.get_foreign_related_value
- instances_dict = dict((instance_attr(inst), inst) for inst in instances)
- db = self._db or router.db_for_read(self.model, instance=instances[0])
- query = {'%s__in' % rel_field.name: instances}
- qs = super(RelatedManager, self).get_queryset().using(db).filter(**query)
- # Since we just bypassed this class' get_queryset(), we must manage
- # the reverse relation manually.
- for rel_obj in qs:
- instance = instances_dict[rel_obj_attr(rel_obj)]
- setattr(rel_obj, rel_field.name, instance)
- cache_name = rel_field.related_query_name()
- return qs, rel_obj_attr, instance_attr, False, cache_name
-
- def add(self, *objs):
- for obj in objs:
- if not isinstance(obj, self.model):
- raise TypeError("'%s' instance expected, got %r" % (self.model._meta.object_name, obj))
- setattr(obj, rel_field.name, self.instance)
- obj.save()
- add.alters_data = True
-
- def create(self, **kwargs):
- kwargs[rel_field.name] = self.instance
- db = router.db_for_write(self.model, instance=self.instance)
- return super(RelatedManager, self.db_manager(db)).create(**kwargs)
- create.alters_data = True
-
- def get_or_create(self, **kwargs):
- # Update kwargs with the related object that this
- # ForeignRelatedObjectsDescriptor knows about.
- kwargs[rel_field.name] = self.instance
- db = router.db_for_write(self.model, instance=self.instance)
- return super(RelatedManager, self.db_manager(db)).get_or_create(**kwargs)
- get_or_create.alters_data = True
-
- # remove() and clear() are only provided if the ForeignKey can have a value of null.
- if rel_field.null:
- def remove(self, *objs):
- val = rel_field.get_foreign_related_value(self.instance)
- for obj in objs:
- # Is obj actually part of this descriptor set?
- if rel_field.get_local_related_value(obj) == val:
- setattr(obj, rel_field.name, None)
- obj.save()
- else:
- raise rel_field.rel.to.DoesNotExist("%r is not related to %r." % (obj, self.instance))
- remove.alters_data = True
-
- def clear(self):
- self.update(**{rel_field.name: None})
- clear.alters_data = True
-
- return RelatedManager
-
-
-def create_many_related_manager(superclass, rel):
- """Creates a manager that subclasses 'superclass' (which is a Manager)
- and adds behavior for many-to-many related objects."""
- class ManyRelatedManager(superclass):
- def __init__(self, model=None, query_field_name=None, instance=None, symmetrical=None,
- source_field_name=None, target_field_name=None, reverse=False,
- through=None, prefetch_cache_name=None):
- super(ManyRelatedManager, self).__init__()
- self.model = model
- self.query_field_name = query_field_name
-
- source_field = through._meta.get_field(source_field_name)
- source_related_fields = source_field.related_fields
-
- self.core_filters = {}
- for lh_field, rh_field in source_related_fields:
- self.core_filters['%s__%s' % (query_field_name, rh_field.name)] = getattr(instance, rh_field.attname)
-
- self.instance = instance
- self.symmetrical = symmetrical
- self.source_field = source_field
- self.source_field_name = source_field_name
- self.target_field_name = target_field_name
- self.reverse = reverse
- self.through = through
- self.prefetch_cache_name = prefetch_cache_name
- self.related_val = source_field.get_foreign_related_value(instance)
- # Used for single column related auto created models
- self._fk_val = self.related_val[0]
- if None in self.related_val:
- raise ValueError('"%r" needs to have a value for field "%s" before '
- 'this many-to-many relationship can be used.' %
- (instance, source_field_name))
- # Even if this relation is not to pk, we require still pk value.
- # The wish is that the instance has been already saved to DB,
- # although having a pk value isn't a guarantee of that.
- if instance.pk is None:
- raise ValueError("%r instance needs to have a primary key value before "
- "a many-to-many relationship can be used." %
- instance.__class__.__name__)
-
-
- def _get_fk_val(self, obj, field_name):
- """
- Returns the correct value for this relationship's foreign key. This
- might be something else than pk value when to_field is used.
- """
- fk = self.through._meta.get_field(field_name)
- if fk.rel.field_name and fk.rel.field_name != fk.rel.to._meta.pk.attname:
- attname = fk.rel.get_related_field().get_attname()
- return fk.get_prep_lookup('exact', getattr(obj, attname))
- else:
- return obj.pk
-
- def get_queryset(self):
- try:
- return self.instance._prefetched_objects_cache[self.prefetch_cache_name]
- except (AttributeError, KeyError):
- db = self._db or router.db_for_read(self.instance.__class__, instance=self.instance)
- return super(ManyRelatedManager, self).get_queryset().using(db)._next_is_sticky().filter(**self.core_filters)
-
- def get_prefetch_queryset(self, instances):
- instance = instances[0]
- db = self._db or router.db_for_read(instance.__class__, instance=instance)
- query = {'%s__in' % self.query_field_name: instances}
- qs = super(ManyRelatedManager, self).get_queryset().using(db)._next_is_sticky().filter(**query)
-
- # M2M: need to annotate the query in order to get the primary model
- # that the secondary model was actually related to. We know that
- # there will already be a join on the join table, so we can just add
- # the select.
-
- # For non-autocreated 'through' models, can't assume we are
- # dealing with PK values.
- fk = self.through._meta.get_field(self.source_field_name)
- join_table = self.through._meta.db_table
- connection = connections[db]
- qn = connection.ops.quote_name
- qs = qs.extra(select=dict(
- ('_prefetch_related_val_%s' % f.attname,
- '%s.%s' % (qn(join_table), qn(f.column))) for f in fk.local_related_fields))
- return (qs,
- lambda result: tuple([getattr(result, '_prefetch_related_val_%s' % f.attname) for f in fk.local_related_fields]),
- lambda inst: tuple([getattr(inst, f.attname) for f in fk.foreign_related_fields]),
- False,
- self.prefetch_cache_name)
-
- # If the ManyToMany relation has an intermediary model,
- # the add and remove methods do not exist.
- if rel.through._meta.auto_created:
- def add(self, *objs):
- self._add_items(self.source_field_name, self.target_field_name, *objs)
-
- # If this is a symmetrical m2m relation to self, add the mirror entry in the m2m table
- if self.symmetrical:
- self._add_items(self.target_field_name, self.source_field_name, *objs)
- add.alters_data = True
-
- def remove(self, *objs):
- self._remove_items(self.source_field_name, self.target_field_name, *objs)
-
- # If this is a symmetrical m2m relation to self, remove the mirror entry in the m2m table
- if self.symmetrical:
- self._remove_items(self.target_field_name, self.source_field_name, *objs)
- remove.alters_data = True
-
- def clear(self):
- self._clear_items(self.source_field_name)
-
- # If this is a symmetrical m2m relation to self, clear the mirror entry in the m2m table
- if self.symmetrical:
- self._clear_items(self.target_field_name)
- clear.alters_data = True
-
- def create(self, **kwargs):
- # This check needs to be done here, since we can't later remove this
- # from the method lookup table, as we do with add and remove.
- if not self.through._meta.auto_created:
- opts = self.through._meta
- raise AttributeError("Cannot use create() on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))
- db = router.db_for_write(self.instance.__class__, instance=self.instance)
- new_obj = super(ManyRelatedManager, self.db_manager(db)).create(**kwargs)
- self.add(new_obj)
- return new_obj
- create.alters_data = True
-
- def get_or_create(self, **kwargs):
- db = router.db_for_write(self.instance.__class__, instance=self.instance)
- obj, created = \
- super(ManyRelatedManager, self.db_manager(db)).get_or_create(**kwargs)
- # We only need to add() if created because if we got an object back
- # from get() then the relationship already exists.
- if created:
- self.add(obj)
- return obj, created
- get_or_create.alters_data = True
-
- def _add_items(self, source_field_name, target_field_name, *objs):
- # source_field_name: the PK fieldname in join table for the source object
- # target_field_name: the PK fieldname in join table for the target object
- # *objs - objects to add. Either object instances, or primary keys of object instances.
-
- # If there aren't any objects, there is nothing to do.
- from django.db.models import Model
- if objs:
- new_ids = set()
- for obj in objs:
- if isinstance(obj, self.model):
- if not router.allow_relation(obj, self.instance):
- raise ValueError('Cannot add "%r": instance is on database "%s", value is on database "%s"' %
- (obj, self.instance._state.db, obj._state.db))
- fk_val = self._get_fk_val(obj, target_field_name)
- if fk_val is None:
- raise ValueError('Cannot add "%r": the value for field "%s" is None' %
- (obj, target_field_name))
- new_ids.add(self._get_fk_val(obj, target_field_name))
- elif isinstance(obj, Model):
- raise TypeError("'%s' instance expected, got %r" % (self.model._meta.object_name, obj))
- else:
- new_ids.add(obj)
- db = router.db_for_write(self.through, instance=self.instance)
- vals = self.through._default_manager.using(db).values_list(target_field_name, flat=True)
- vals = vals.filter(**{
- source_field_name: self._fk_val,
- '%s__in' % target_field_name: new_ids,
- })
- new_ids = new_ids - set(vals)
-
- if self.reverse or source_field_name == self.source_field_name:
- # Don't send the signal when we are inserting the
- # duplicate data row for symmetrical reverse entries.
- signals.m2m_changed.send(sender=self.through, action='pre_add',
- instance=self.instance, reverse=self.reverse,
- model=self.model, pk_set=new_ids, using=db)
- # Add the ones that aren't there already
- self.through._default_manager.using(db).bulk_create([
- self.through(**{
- '%s_id' % source_field_name: self._fk_val,
- '%s_id' % target_field_name: obj_id,
- })
- for obj_id in new_ids
- ])
-
- if self.reverse or source_field_name == self.source_field_name:
- # Don't send the signal when we are inserting the
- # duplicate data row for symmetrical reverse entries.
- signals.m2m_changed.send(sender=self.through, action='post_add',
- instance=self.instance, reverse=self.reverse,
- model=self.model, pk_set=new_ids, using=db)
-
- def _remove_items(self, source_field_name, target_field_name, *objs):
- # source_field_name: the PK colname in join table for the source object
- # target_field_name: the PK colname in join table for the target object
- # *objs - objects to remove
-
- # If there aren't any objects, there is nothing to do.
- if objs:
- # Check that all the objects are of the right type
- old_ids = set()
- for obj in objs:
- if isinstance(obj, self.model):
- old_ids.add(self._get_fk_val(obj, target_field_name))
- else:
- old_ids.add(obj)
- # Work out what DB we're operating on
- db = router.db_for_write(self.through, instance=self.instance)
- # Send a signal to the other end if need be.
- if self.reverse or source_field_name == self.source_field_name:
- # Don't send the signal when we are deleting the
- # duplicate data row for symmetrical reverse entries.
- signals.m2m_changed.send(sender=self.through, action="pre_remove",
- instance=self.instance, reverse=self.reverse,
- model=self.model, pk_set=old_ids, using=db)
- # Remove the specified objects from the join table
- self.through._default_manager.using(db).filter(**{
- source_field_name: self._fk_val,
- '%s__in' % target_field_name: old_ids
- }).delete()
- if self.reverse or source_field_name == self.source_field_name:
- # Don't send the signal when we are deleting the
- # duplicate data row for symmetrical reverse entries.
- signals.m2m_changed.send(sender=self.through, action="post_remove",
- instance=self.instance, reverse=self.reverse,
- model=self.model, pk_set=old_ids, using=db)
-
- def _clear_items(self, source_field_name):
- db = router.db_for_write(self.through, instance=self.instance)
- # source_field_name: the PK colname in join table for the source object
- if self.reverse or source_field_name == self.source_field_name:
- # Don't send the signal when we are clearing the
- # duplicate data rows for symmetrical reverse entries.
- signals.m2m_changed.send(sender=self.through, action="pre_clear",
- instance=self.instance, reverse=self.reverse,
- model=self.model, pk_set=None, using=db)
- self.through._default_manager.using(db).filter(**{
- source_field_name: self.related_val
- }).delete()
- if self.reverse or source_field_name == self.source_field_name:
- # Don't send the signal when we are clearing the
- # duplicate data rows for symmetrical reverse entries.
- signals.m2m_changed.send(sender=self.through, action="post_clear",
- instance=self.instance, reverse=self.reverse,
- model=self.model, pk_set=None, using=db)
-
- return ManyRelatedManager
-
-
-class ManyRelatedObjectsDescriptor(object):
- # This class provides the functionality that makes the related-object
- # managers available as attributes on a model class, for fields that have
- # multiple "remote" values and have a ManyToManyField pointed at them by
- # some other model (rather than having a ManyToManyField themselves).
- # In the example "publication.article_set", the article_set attribute is a
- # ManyRelatedObjectsDescriptor instance.
- def __init__(self, related):
- self.related = related # RelatedObject instance
-
- @cached_property
- def related_manager_cls(self):
- # Dynamically create a class that subclasses the related
- # model's default manager.
- return create_many_related_manager(
- self.related.model._default_manager.__class__,
- self.related.field.rel
- )
-
- def __get__(self, instance, instance_type=None):
- if instance is None:
- return self
-
- rel_model = self.related.model
-
- manager = self.related_manager_cls(
- model=rel_model,
- query_field_name=self.related.field.name,
- prefetch_cache_name=self.related.field.related_query_name(),
- instance=instance,
- symmetrical=False,
- source_field_name=self.related.field.m2m_reverse_field_name(),
- target_field_name=self.related.field.m2m_field_name(),
- reverse=True,
- through=self.related.field.rel.through,
- )
-
- return manager
-
- def __set__(self, instance, value):
- if not self.related.field.rel.through._meta.auto_created:
- opts = self.related.field.rel.through._meta
- raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))
-
- manager = self.__get__(instance)
- manager.clear()
- manager.add(*value)
-
-
-class ReverseManyRelatedObjectsDescriptor(object):
- # This class provides the functionality that makes the related-object
- # managers available as attributes on a model class, for fields that have
- # multiple "remote" values and have a ManyToManyField defined in their
- # model (rather than having another model pointed *at* them).
- # In the example "article.publications", the publications attribute is a
- # ReverseManyRelatedObjectsDescriptor instance.
- def __init__(self, m2m_field):
- self.field = m2m_field
-
- @property
- def through(self):
- # through is provided so that you have easy access to the through
- # model (Book.authors.through) for inlines, etc. This is done as
- # a property to ensure that the fully resolved value is returned.
- return self.field.rel.through
-
- @cached_property
- def related_manager_cls(self):
- # Dynamically create a class that subclasses the related model's
- # default manager.
- return create_many_related_manager(
- self.field.rel.to._default_manager.__class__,
- self.field.rel
- )
-
- def __get__(self, instance, instance_type=None):
- if instance is None:
- return self
-
- manager = self.related_manager_cls(
- model=self.field.rel.to,
- query_field_name=self.field.related_query_name(),
- prefetch_cache_name=self.field.name,
- instance=instance,
- symmetrical=self.field.rel.symmetrical,
- source_field_name=self.field.m2m_field_name(),
- target_field_name=self.field.m2m_reverse_field_name(),
- reverse=False,
- through=self.field.rel.through,
- )
-
- return manager
-
- def __set__(self, instance, value):
- if not self.field.rel.through._meta.auto_created:
- opts = self.field.rel.through._meta
- raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))
-
- manager = self.__get__(instance)
- # clear() can change expected output of 'value' queryset, we force evaluation
- # of queryset before clear; ticket #19816
- value = tuple(value)
- manager.clear()
- manager.add(*value)
-
-class ForeignObjectRel(object):
- def __init__(self, field, to, related_name=None, limit_choices_to=None,
- parent_link=False, on_delete=None, related_query_name=None):
- try:
- to._meta
- except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
- assert isinstance(to, six.string_types), "'to' must be either a model, a model name or the string %r" % RECURSIVE_RELATIONSHIP_CONSTANT
-
- self.field = field
- self.to = to
- self.related_name = related_name
- self.related_query_name = related_query_name
- self.limit_choices_to = {} if limit_choices_to is None else limit_choices_to
- self.multiple = True
- self.parent_link = parent_link
- self.on_delete = on_delete
-
- def is_hidden(self):
- "Should the related object be hidden?"
- return self.related_name and self.related_name[-1] == '+'
-
- def get_joining_columns(self):
- return self.field.get_reverse_joining_columns()
-
- def get_extra_restriction(self, where_class, alias, related_alias):
- return self.field.get_extra_restriction(where_class, related_alias, alias)
-
- def set_field_name(self):
- """
- Sets the related field's name, this is not available until later stages
- of app loading, so set_field_name is called from
- set_attributes_from_rel()
- """
- # By default foreign object doesn't relate to any remote field (for
- # example custom multicolumn joins currently have no remote field).
- self.field_name = None
-
-class ManyToOneRel(ForeignObjectRel):
- def __init__(self, field, to, field_name, related_name=None, limit_choices_to=None,
- parent_link=False, on_delete=None, related_query_name=None):
- super(ManyToOneRel, self).__init__(
- field, to, related_name=related_name, limit_choices_to=limit_choices_to,
- parent_link=parent_link, on_delete=on_delete, related_query_name=related_query_name)
- self.field_name = field_name
-
- def get_related_field(self):
- """
- Returns the Field in the 'to' object to which this relationship is
- tied.
- """
- data = self.to._meta.get_field_by_name(self.field_name)
- if not data[2]:
- raise FieldDoesNotExist("No related field named '%s'" %
- self.field_name)
- return data[0]
-
- def set_field_name(self):
- self.field_name = self.field_name or self.to._meta.pk.name
-
-
-class OneToOneRel(ManyToOneRel):
- def __init__(self, field, to, field_name, related_name=None, limit_choices_to=None,
- parent_link=False, on_delete=None, related_query_name=None):
- super(OneToOneRel, self).__init__(field, to, field_name,
- related_name=related_name, limit_choices_to=limit_choices_to,
- parent_link=parent_link, on_delete=on_delete, related_query_name=related_query_name,
- )
- self.multiple = False
-
-
-class ManyToManyRel(object):
- def __init__(self, to, related_name=None, limit_choices_to=None,
- symmetrical=True, through=None, db_constraint=True, related_query_name=None):
- if through and not db_constraint:
- raise ValueError("Can't supply a through model and db_constraint=False")
- self.to = to
- self.related_name = related_name
- self.related_query_name = related_query_name
- if limit_choices_to is None:
- limit_choices_to = {}
- self.limit_choices_to = limit_choices_to
- self.symmetrical = symmetrical
- self.multiple = True
- self.through = through
- self.db_constraint = db_constraint
-
- def is_hidden(self):
- "Should the related object be hidden?"
- return self.related_name and self.related_name[-1] == '+'
-
- def get_related_field(self):
- """
- Returns the field in the to' object to which this relationship is tied
- (this is always the primary key on the target model). Provided for
- symmetry with ManyToOneRel.
- """
- return self.to._meta.pk
-
-
-class ForeignObject(RelatedField):
- requires_unique_target = True
- generate_reverse_relation = True
-
- def __init__(self, to, from_fields, to_fields, **kwargs):
- self.from_fields = from_fields
- self.to_fields = to_fields
-
- if 'rel' not in kwargs:
- kwargs['rel'] = ForeignObjectRel(
- self, to,
- related_name=kwargs.pop('related_name', None),
- related_query_name=kwargs.pop('related_query_name', None),
- limit_choices_to=kwargs.pop('limit_choices_to', None),
- parent_link=kwargs.pop('parent_link', False),
- on_delete=kwargs.pop('on_delete', CASCADE),
- )
- kwargs['verbose_name'] = kwargs.get('verbose_name', None)
-
- super(ForeignObject, self).__init__(**kwargs)
-
- def resolve_related_fields(self):
- if len(self.from_fields) < 1 or len(self.from_fields) != len(self.to_fields):
- raise ValueError('Foreign Object from and to fields must be the same non-zero length')
- related_fields = []
- for index in range(len(self.from_fields)):
- from_field_name = self.from_fields[index]
- to_field_name = self.to_fields[index]
- from_field = (self if from_field_name == 'self'
- else self.opts.get_field_by_name(from_field_name)[0])
- to_field = (self.rel.to._meta.pk if to_field_name is None
- else self.rel.to._meta.get_field_by_name(to_field_name)[0])
- related_fields.append((from_field, to_field))
- return related_fields
-
- @property
- def related_fields(self):
- if not hasattr(self, '_related_fields'):
- self._related_fields = self.resolve_related_fields()
- return self._related_fields
-
- @property
- def reverse_related_fields(self):
- return [(rhs_field, lhs_field) for lhs_field, rhs_field in self.related_fields]
-
- @property
- def local_related_fields(self):
- return tuple([lhs_field for lhs_field, rhs_field in self.related_fields])
-
- @property
- def foreign_related_fields(self):
- return tuple([rhs_field for lhs_field, rhs_field in self.related_fields])
-
- def get_local_related_value(self, instance):
- return self.get_instance_value_for_fields(instance, self.local_related_fields)
-
- def get_foreign_related_value(self, instance):
- return self.get_instance_value_for_fields(instance, self.foreign_related_fields)
-
- @staticmethod
- def get_instance_value_for_fields(instance, fields):
- ret = []
- for field in fields:
- # Gotcha: in some cases (like fixture loading) a model can have
- # different values in parent_ptr_id and parent's id. So, use
- # instance.pk (that is, parent_ptr_id) when asked for instance.id.
- if field.primary_key:
- ret.append(instance.pk)
- else:
- ret.append(getattr(instance, field.attname))
- return tuple(ret)
-
- def get_attname_column(self):
- attname, column = super(ForeignObject, self).get_attname_column()
- return attname, None
-
- def get_joining_columns(self, reverse_join=False):
- source = self.reverse_related_fields if reverse_join else self.related_fields
- return tuple([(lhs_field.column, rhs_field.column) for lhs_field, rhs_field in source])
-
- def get_reverse_joining_columns(self):
- return self.get_joining_columns(reverse_join=True)
-
- def get_extra_descriptor_filter(self, instance):
- """
- Returns an extra filter condition for related object fetching when
- user does 'instance.fieldname', that is the extra filter is used in
- the descriptor of the field.
-
- The filter should be either a dict usable in .filter(**kwargs) call or
- a Q-object. The condition will be ANDed together with the relation's
- joining columns.
-
- A parallel method is get_extra_restriction() which is used in
- JOIN and subquery conditions.
- """
- return {}
-
- def get_extra_restriction(self, where_class, alias, related_alias):
- """
- Returns a pair condition used for joining and subquery pushdown. The
- condition is something that responds to as_sql(qn, connection) method.
-
- Note that currently referring both the 'alias' and 'related_alias'
- will not work in some conditions, like subquery pushdown.
-
- A parallel method is get_extra_descriptor_filter() which is used in
- instance.fieldname related object fetching.
- """
- return None
-
- def get_path_info(self):
- """
- Get path from this field to the related model.
- """
- opts = self.rel.to._meta
- from_opts = self.model._meta
- return [PathInfo(from_opts, opts, self.foreign_related_fields, self, False, True)]
-
- def get_reverse_path_info(self):
- """
- Get path from the related model to this field's model.
- """
- opts = self.model._meta
- from_opts = self.rel.to._meta
- pathinfos = [PathInfo(from_opts, opts, (opts.pk,), self.rel, not self.unique, False)]
- return pathinfos
-
- def get_lookup_constraint(self, constraint_class, alias, targets, sources, lookup_type,
- raw_value):
- from django.db.models.sql.where import SubqueryConstraint, Constraint, AND, OR
- root_constraint = constraint_class()
- assert len(targets) == len(sources)
-
- def get_normalized_value(value):
-
- from django.db.models import Model
- if isinstance(value, Model):
- value_list = []
- for source in sources:
- # Account for one-to-one relations when sent a different model
- while not isinstance(value, source.model) and source.rel:
- source = source.rel.to._meta.get_field(source.rel.field_name)
- value_list.append(getattr(value, source.attname))
- return tuple(value_list)
- elif not isinstance(value, tuple):
- return (value,)
- return value
-
- is_multicolumn = len(self.related_fields) > 1
- if (hasattr(raw_value, '_as_sql') or
- hasattr(raw_value, 'get_compiler')):
- root_constraint.add(SubqueryConstraint(alias, [target.column for target in targets],
- [source.name for source in sources], raw_value),
- AND)
- elif lookup_type == 'isnull':
- root_constraint.add(
- (Constraint(alias, targets[0].column, targets[0]), lookup_type, raw_value), AND)
- elif (lookup_type == 'exact' or (lookup_type in ['gt', 'lt', 'gte', 'lte']
- and not is_multicolumn)):
- value = get_normalized_value(raw_value)
- for index, source in enumerate(sources):
- root_constraint.add(
- (Constraint(alias, targets[index].column, sources[index]), lookup_type,
- value[index]), AND)
- elif lookup_type in ['range', 'in'] and not is_multicolumn:
- values = [get_normalized_value(value) for value in raw_value]
- value = [val[0] for val in values]
- root_constraint.add(
- (Constraint(alias, targets[0].column, sources[0]), lookup_type, value), AND)
- elif lookup_type == 'in':
- values = [get_normalized_value(value) for value in raw_value]
- for value in values:
- value_constraint = constraint_class()
- for index, target in enumerate(targets):
- value_constraint.add(
- (Constraint(alias, target.column, sources[index]), 'exact', value[index]),
- AND)
- root_constraint.add(value_constraint, OR)
- else:
- raise TypeError('Related Field got invalid lookup: %s' % lookup_type)
- return root_constraint
-
- @property
- def attnames(self):
- return tuple([field.attname for field in self.local_related_fields])
-
- def get_defaults(self):
- return tuple([field.get_default() for field in self.local_related_fields])
-
- def contribute_to_class(self, cls, name, virtual_only=False):
- super(ForeignObject, self).contribute_to_class(cls, name, virtual_only=virtual_only)
- setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self))
-
- def contribute_to_related_class(self, cls, related):
- # Internal FK's - i.e., those with a related name ending with '+' -
- # and swapped models don't get a related descriptor.
- if not self.rel.is_hidden() and not related.model._meta.swapped:
- setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related))
- if self.rel.limit_choices_to:
- cls._meta.related_fkey_lookups.append(self.rel.limit_choices_to)
-
-
-class ForeignKey(ForeignObject):
- empty_strings_allowed = False
- default_error_messages = {
- 'invalid': _('%(model)s instance with pk %(pk)r does not exist.')
- }
- description = _("Foreign Key (type determined by related field)")
-
- def __init__(self, to, to_field=None, rel_class=ManyToOneRel,
- db_constraint=True, **kwargs):
- try:
- to_name = to._meta.object_name.lower()
- except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
- assert isinstance(to, six.string_types), "%s(%r) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT)
- else:
- assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name)
- # For backwards compatibility purposes, we need to *try* and set
- # the to_field during FK construction. It won't be guaranteed to
- # be correct until contribute_to_class is called. Refs #12190.
- to_field = to_field or (to._meta.pk and to._meta.pk.name)
-
- if 'db_index' not in kwargs:
- kwargs['db_index'] = True
-
- self.db_constraint = db_constraint
-
- kwargs['rel'] = rel_class(
- self, to, to_field,
- related_name=kwargs.pop('related_name', None),
- related_query_name=kwargs.pop('related_query_name', None),
- limit_choices_to=kwargs.pop('limit_choices_to', None),
- parent_link=kwargs.pop('parent_link', False),
- on_delete=kwargs.pop('on_delete', CASCADE),
- )
- super(ForeignKey, self).__init__(to, ['self'], [to_field], **kwargs)
-
- @property
- def related_field(self):
- return self.foreign_related_fields[0]
-
- def get_reverse_path_info(self):
- """
- Get path from the related model to this field's model.
- """
- opts = self.model._meta
- from_opts = self.rel.to._meta
- pathinfos = [PathInfo(from_opts, opts, (opts.pk,), self.rel, not self.unique, False)]
- return pathinfos
-
- def validate(self, value, model_instance):
- if self.rel.parent_link:
- return
- super(ForeignKey, self).validate(value, model_instance)
- if value is None:
- return
-
- using = router.db_for_read(model_instance.__class__, instance=model_instance)
- qs = self.rel.to._default_manager.using(using).filter(
- **{self.rel.field_name: value}
- )
- qs = qs.complex_filter(self.rel.limit_choices_to)
- if not qs.exists():
- raise exceptions.ValidationError(
- self.error_messages['invalid'],
- code='invalid',
- params={'model': self.rel.to._meta.verbose_name, 'pk': value},
- )
-
- def get_attname(self):
- return '%s_id' % self.name
-
- def get_attname_column(self):
- attname = self.get_attname()
- column = self.db_column or attname
- return attname, column
-
- def get_validator_unique_lookup_type(self):
- return '%s__%s__exact' % (self.name, self.related_field.name)
-
- def get_default(self):
- "Here we check if the default value is an object and return the to_field if so."
- field_default = super(ForeignKey, self).get_default()
- if isinstance(field_default, self.rel.to):
- return getattr(field_default, self.related_field.attname)
- return field_default
-
- def get_db_prep_save(self, value, connection):
- if value == '' or value == None:
- return None
- else:
- return self.related_field.get_db_prep_save(value,
- connection=connection)
-
- def value_to_string(self, obj):
- if not obj:
- # In required many-to-one fields with only one available choice,
- # select that one available choice. Note: For SelectFields
- # we have to check that the length of choices is *2*, not 1,
- # because SelectFields always have an initial "blank" value.
- if not self.blank and self.choices:
- choice_list = self.get_choices_default()
- if len(choice_list) == 2:
- return smart_text(choice_list[1][0])
- return super(ForeignKey, self).value_to_string(obj)
-
- def contribute_to_related_class(self, cls, related):
- super(ForeignKey, self).contribute_to_related_class(cls, related)
- if self.rel.field_name is None:
- self.rel.field_name = cls._meta.pk.name
-
- def formfield(self, **kwargs):
- db = kwargs.pop('using', None)
- if isinstance(self.rel.to, six.string_types):
- raise ValueError("Cannot create form field for %r yet, because "
- "its related model %r has not been loaded yet" %
- (self.name, self.rel.to))
- defaults = {
- 'form_class': forms.ModelChoiceField,
- 'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to),
- 'to_field_name': self.rel.field_name,
- }
- defaults.update(kwargs)
- return super(ForeignKey, self).formfield(**defaults)
-
- def db_type(self, connection):
- # The database column type of a ForeignKey is the column type
- # of the field to which it points. An exception is if the ForeignKey
- # points to an AutoField/PositiveIntegerField/PositiveSmallIntegerField,
- # in which case the column type is simply that of an IntegerField.
- # If the database needs similar types for key fields however, the only
- # thing we can do is making AutoField an IntegerField.
- rel_field = self.related_field
- if (isinstance(rel_field, AutoField) or
- (not connection.features.related_fields_match_type and
- isinstance(rel_field, (PositiveIntegerField,
- PositiveSmallIntegerField)))):
- return IntegerField().db_type(connection=connection)
- return rel_field.db_type(connection=connection)
-
-
-class OneToOneField(ForeignKey):
- """
- A OneToOneField is essentially the same as a ForeignKey, with the exception
- that always carries a "unique" constraint with it and the reverse relation
- always returns the object pointed to (since there will only ever be one),
- rather than returning a list.
- """
- description = _("One-to-one relationship")
-
- def __init__(self, to, to_field=None, **kwargs):
- kwargs['unique'] = True
- super(OneToOneField, self).__init__(to, to_field, OneToOneRel, **kwargs)
-
- def contribute_to_related_class(self, cls, related):
- setattr(cls, related.get_accessor_name(),
- SingleRelatedObjectDescriptor(related))
-
- def formfield(self, **kwargs):
- if self.rel.parent_link:
- return None
- return super(OneToOneField, self).formfield(**kwargs)
-
- def save_form_data(self, instance, data):
- if isinstance(data, self.rel.to):
- setattr(instance, self.name, data)
- else:
- setattr(instance, self.attname, data)
-
-
-def create_many_to_many_intermediary_model(field, klass):
- from django.db import models
- managed = True
- if isinstance(field.rel.to, six.string_types) and field.rel.to != RECURSIVE_RELATIONSHIP_CONSTANT:
- to_model = field.rel.to
- to = to_model.split('.')[-1]
-
- def set_managed(field, model, cls):
- field.rel.through._meta.managed = model._meta.managed or cls._meta.managed
- add_lazy_relation(klass, field, to_model, set_managed)
- elif isinstance(field.rel.to, six.string_types):
- to = klass._meta.object_name
- to_model = klass
- managed = klass._meta.managed
- else:
- to = field.rel.to._meta.object_name
- to_model = field.rel.to
- managed = klass._meta.managed or to_model._meta.managed
- name = '%s_%s' % (klass._meta.object_name, field.name)
- if field.rel.to == RECURSIVE_RELATIONSHIP_CONSTANT or to == klass._meta.object_name:
- from_ = 'from_%s' % to.lower()
- to = 'to_%s' % to.lower()
- else:
- from_ = klass._meta.model_name
- to = to.lower()
- meta = type('Meta', (object,), {
- 'db_table': field._get_m2m_db_table(klass._meta),
- 'managed': managed,
- 'auto_created': klass,
- 'app_label': klass._meta.app_label,
- 'db_tablespace': klass._meta.db_tablespace,
- 'unique_together': (from_, to),
- 'verbose_name': '%(from)s-%(to)s relationship' % {'from': from_, 'to': to},
- 'verbose_name_plural': '%(from)s-%(to)s relationships' % {'from': from_, 'to': to},
- })
- # Construct and return the new class.
- return type(str(name), (models.Model,), {
- 'Meta': meta,
- '__module__': klass.__module__,
- from_: models.ForeignKey(klass, related_name='%s+' % name, db_tablespace=field.db_tablespace, db_constraint=field.rel.db_constraint),
- to: models.ForeignKey(to_model, related_name='%s+' % name, db_tablespace=field.db_tablespace, db_constraint=field.rel.db_constraint)
- })
-
-
-class ManyToManyField(RelatedField):
- description = _("Many-to-many relationship")
-
- def __init__(self, to, db_constraint=True, **kwargs):
- try:
- assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name)
- except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
- assert isinstance(to, six.string_types), "%s(%r) is invalid. First parameter to ManyToManyField must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT)
- # Python 2.6 and earlier require dictionary keys to be of str type,
- # not unicode and class names must be ASCII (in Python 2.x), so we
- # forcibly coerce it here (breaks early if there's a problem).
- to = str(to)
-
- kwargs['verbose_name'] = kwargs.get('verbose_name', None)
- kwargs['rel'] = ManyToManyRel(to,
- related_name=kwargs.pop('related_name', None),
- related_query_name=kwargs.pop('related_query_name', None),
- limit_choices_to=kwargs.pop('limit_choices_to', None),
- symmetrical=kwargs.pop('symmetrical', to == RECURSIVE_RELATIONSHIP_CONSTANT),
- through=kwargs.pop('through', None),
- db_constraint=db_constraint,
- )
-
- self.db_table = kwargs.pop('db_table', None)
- if kwargs['rel'].through is not None:
- assert self.db_table is None, "Cannot specify a db_table if an intermediary model is used."
-
- super(ManyToManyField, self).__init__(**kwargs)
-
- def _get_path_info(self, direct=False):
- """
- Called by both direct an indirect m2m traversal.
- """
- pathinfos = []
- int_model = self.rel.through
- linkfield1 = int_model._meta.get_field_by_name(self.m2m_field_name())[0]
- linkfield2 = int_model._meta.get_field_by_name(self.m2m_reverse_field_name())[0]
- if direct:
- join1infos = linkfield1.get_reverse_path_info()
- join2infos = linkfield2.get_path_info()
- else:
- join1infos = linkfield2.get_reverse_path_info()
- join2infos = linkfield1.get_path_info()
- pathinfos.extend(join1infos)
- pathinfos.extend(join2infos)
- return pathinfos
-
- def get_path_info(self):
- return self._get_path_info(direct=True)
-
- def get_reverse_path_info(self):
- return self._get_path_info(direct=False)
-
- def get_choices_default(self):
- return Field.get_choices(self, include_blank=False)
-
- def _get_m2m_db_table(self, opts):
- "Function that can be curried to provide the m2m table name for this relation"
- if self.rel.through is not None:
- return self.rel.through._meta.db_table
- elif self.db_table:
- return self.db_table
- else:
- return util.truncate_name('%s_%s' % (opts.db_table, self.name),
- connection.ops.max_name_length())
-
- def _get_m2m_attr(self, related, attr):
- "Function that can be curried to provide the source accessor or DB column name for the m2m table"
- cache_attr = '_m2m_%s_cache' % attr
- if hasattr(self, cache_attr):
- return getattr(self, cache_attr)
- for f in self.rel.through._meta.fields:
- if hasattr(f, 'rel') and f.rel and f.rel.to == related.model:
- setattr(self, cache_attr, getattr(f, attr))
- return getattr(self, cache_attr)
-
- def _get_m2m_reverse_attr(self, related, attr):
- "Function that can be curried to provide the related accessor or DB column name for the m2m table"
- cache_attr = '_m2m_reverse_%s_cache' % attr
- if hasattr(self, cache_attr):
- return getattr(self, cache_attr)
- found = False
- for f in self.rel.through._meta.fields:
- if hasattr(f, 'rel') and f.rel and f.rel.to == related.parent_model:
- if related.model == related.parent_model:
- # If this is an m2m-intermediate to self,
- # the first foreign key you find will be
- # the source column. Keep searching for
- # the second foreign key.
- if found:
- setattr(self, cache_attr, getattr(f, attr))
- break
- else:
- found = True
- else:
- setattr(self, cache_attr, getattr(f, attr))
- break
- return getattr(self, cache_attr)
-
- def value_to_string(self, obj):
- data = ''
- if obj:
- qs = getattr(obj, self.name).all()
- data = [instance._get_pk_val() for instance in qs]
- else:
- # In required many-to-many fields with only one available choice,
- # select that one available choice.
- if not self.blank:
- choices_list = self.get_choices_default()
- if len(choices_list) == 1:
- data = [choices_list[0][0]]
- return smart_text(data)
-
- def contribute_to_class(self, cls, name):
- # To support multiple relations to self, it's useful to have a non-None
- # related name on symmetrical relations for internal reasons. The
- # concept doesn't make a lot of sense externally ("you want me to
- # specify *what* on my non-reversible relation?!"), so we set it up
- # automatically. The funky name reduces the chance of an accidental
- # clash.
- if self.rel.symmetrical and (self.rel.to == "self" or self.rel.to == cls._meta.object_name):
- self.rel.related_name = "%s_rel_+" % name
-
- super(ManyToManyField, self).contribute_to_class(cls, name)
-
- # The intermediate m2m model is not auto created if:
- # 1) There is a manually specified intermediate, or
- # 2) The class owning the m2m field is abstract.
- # 3) The class owning the m2m field has been swapped out.
- if not self.rel.through and not cls._meta.abstract and not cls._meta.swapped:
- self.rel.through = create_many_to_many_intermediary_model(self, cls)
-
- # Add the descriptor for the m2m relation
- setattr(cls, self.name, ReverseManyRelatedObjectsDescriptor(self))
-
- # Set up the accessor for the m2m table name for the relation
- self.m2m_db_table = curry(self._get_m2m_db_table, cls._meta)
-
- # Populate some necessary rel arguments so that cross-app relations
- # work correctly.
- if isinstance(self.rel.through, six.string_types):
- def resolve_through_model(field, model, cls):
- field.rel.through = model
- add_lazy_relation(cls, self, self.rel.through, resolve_through_model)
-
- def contribute_to_related_class(self, cls, related):
- # Internal M2Ms (i.e., those with a related name ending with '+')
- # and swapped models don't get a related descriptor.
- if not self.rel.is_hidden() and not related.model._meta.swapped:
- setattr(cls, related.get_accessor_name(), ManyRelatedObjectsDescriptor(related))
-
- # Set up the accessors for the column names on the m2m table
- self.m2m_column_name = curry(self._get_m2m_attr, related, 'column')
- self.m2m_reverse_name = curry(self._get_m2m_reverse_attr, related, 'column')
-
- self.m2m_field_name = curry(self._get_m2m_attr, related, 'name')
- self.m2m_reverse_field_name = curry(self._get_m2m_reverse_attr, related, 'name')
-
- get_m2m_rel = curry(self._get_m2m_attr, related, 'rel')
- self.m2m_target_field_name = lambda: get_m2m_rel().field_name
- get_m2m_reverse_rel = curry(self._get_m2m_reverse_attr, related, 'rel')
- self.m2m_reverse_target_field_name = lambda: get_m2m_reverse_rel().field_name
-
- def set_attributes_from_rel(self):
- pass
-
- def value_from_object(self, obj):
- "Returns the value of this field in the given model instance."
- return getattr(obj, self.attname).all()
-
- def save_form_data(self, instance, data):
- setattr(instance, self.attname, data)
-
- def formfield(self, **kwargs):
- db = kwargs.pop('using', None)
- defaults = {
- 'form_class': forms.ModelMultipleChoiceField,
- 'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to)
- }
- defaults.update(kwargs)
- # If initial is passed in, it's a list of related objects, but the
- # MultipleChoiceField takes a list of IDs.
- if defaults.get('initial') is not None:
- initial = defaults['initial']
- if callable(initial):
- initial = initial()
- defaults['initial'] = [i._get_pk_val() for i in initial]
- return super(ManyToManyField, self).formfield(**defaults)
diff --git a/lib/python2.7/site-packages/django/db/models/fields/subclassing.py b/lib/python2.7/site-packages/django/db/models/fields/subclassing.py
deleted file mode 100644
index e6153ae..0000000
--- a/lib/python2.7/site-packages/django/db/models/fields/subclassing.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-Convenience routines for creating non-trivial Field subclasses, as well as
-backwards compatibility utilities.
-
-Add SubfieldBase as the metaclass for your Field subclass, implement
-to_python() and the other necessary methods and everything will work
-seamlessly.
-"""
-
-class SubfieldBase(type):
- """
- A metaclass for custom Field subclasses. This ensures the model's attribute
- has the descriptor protocol attached to it.
- """
- def __new__(cls, name, bases, attrs):
- new_class = super(SubfieldBase, cls).__new__(cls, name, bases, attrs)
- new_class.contribute_to_class = make_contrib(
- new_class, attrs.get('contribute_to_class')
- )
- return new_class
-
-class Creator(object):
- """
- A placeholder class that provides a way to set the attribute on the model.
- """
- def __init__(self, field):
- self.field = field
-
- def __get__(self, obj, type=None):
- if obj is None:
- raise AttributeError('Can only be accessed via an instance.')
- return obj.__dict__[self.field.name]
-
- def __set__(self, obj, value):
- obj.__dict__[self.field.name] = self.field.to_python(value)
-
-def make_contrib(superclass, func=None):
- """
- Returns a suitable contribute_to_class() method for the Field subclass.
-
- If 'func' is passed in, it is the existing contribute_to_class() method on
- the subclass and it is called before anything else. It is assumed in this
- case that the existing contribute_to_class() calls all the necessary
- superclass methods.
- """
- def contribute_to_class(self, cls, name):
- if func:
- func(self, cls, name)
- else:
- super(superclass, self).contribute_to_class(cls, name)
- setattr(cls, self.name, Creator(self))
-
- return contribute_to_class
diff --git a/lib/python2.7/site-packages/django/db/models/loading.py b/lib/python2.7/site-packages/django/db/models/loading.py
deleted file mode 100644
index bb87728..0000000
--- a/lib/python2.7/site-packages/django/db/models/loading.py
+++ /dev/null
@@ -1,327 +0,0 @@
-"Utilities for loading models and the modules that contain them."
-
-from django.conf import settings
-from django.core.exceptions import ImproperlyConfigured
-from django.utils.datastructures import SortedDict
-from django.utils.importlib import import_module
-from django.utils.module_loading import module_has_submodule
-from django.utils._os import upath
-from django.utils import six
-
-import imp
-import sys
-import os
-
-__all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models',
- 'load_app', 'app_cache_ready')
-
-class UnavailableApp(Exception):
- pass
-
-class AppCache(object):
- """
- A cache that stores installed applications and their models. Used to
- provide reverse-relations and for app introspection (e.g. admin).
- """
- # Use the Borg pattern to share state between all instances. Details at
- # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531.
- __shared_state = dict(
- # Keys of app_store are the model modules for each application.
- app_store=SortedDict(),
-
- # Mapping of installed app_labels to model modules for that app.
- app_labels={},
-
- # Mapping of app_labels to a dictionary of model names to model code.
- # May contain apps that are not installed.
- app_models=SortedDict(),
-
- # Mapping of app_labels to errors raised when trying to import the app.
- app_errors={},
-
- # -- Everything below here is only used when populating the cache --
- loaded=False,
- handled=set(),
- postponed=[],
- nesting_level=0,
- _get_models_cache={},
- available_apps=None,
- )
-
- def __init__(self):
- self.__dict__ = self.__shared_state
-
- def _populate(self):
- """
- Fill in all the cache information. This method is threadsafe, in the
- sense that every caller will see the same state upon return, and if the
- cache is already initialised, it does no work.
- """
- if self.loaded:
- return
- # Note that we want to use the import lock here - the app loading is
- # in many cases initiated implicitly by importing, and thus it is
- # possible to end up in deadlock when one thread initiates loading
- # without holding the importer lock and another thread then tries to
- # import something which also launches the app loading. For details of
- # this situation see #18251.
- imp.acquire_lock()
- try:
- if self.loaded:
- return
- for app_name in settings.INSTALLED_APPS:
- if app_name in self.handled:
- continue
- self.load_app(app_name, True)
- if not self.nesting_level:
- for app_name in self.postponed:
- self.load_app(app_name)
- self.loaded = True
- finally:
- imp.release_lock()
-
- def _label_for(self, app_mod):
- """
- Return app_label for given models module.
-
- """
- return app_mod.__name__.split('.')[-2]
-
- def load_app(self, app_name, can_postpone=False):
- """
- Loads the app with the provided fully qualified name, and returns the
- model module.
- """
- self.handled.add(app_name)
- self.nesting_level += 1
- app_module = import_module(app_name)
- try:
- models = import_module('%s.models' % app_name)
- except ImportError:
- self.nesting_level -= 1
- # If the app doesn't have a models module, we can just ignore the
- # ImportError and return no models for it.
- if not module_has_submodule(app_module, 'models'):
- return None
- # But if the app does have a models module, we need to figure out
- # whether to suppress or propagate the error. If can_postpone is
- # True then it may be that the package is still being imported by
- # Python and the models module isn't available yet. So we add the
- # app to the postponed list and we'll try it again after all the
- # recursion has finished (in populate). If can_postpone is False
- # then it's time to raise the ImportError.
- else:
- if can_postpone:
- self.postponed.append(app_name)
- return None
- else:
- raise
-
- self.nesting_level -= 1
- if models not in self.app_store:
- self.app_store[models] = len(self.app_store)
- self.app_labels[self._label_for(models)] = models
- return models
-
- def app_cache_ready(self):
- """
- Returns true if the model cache is fully populated.
-
- Useful for code that wants to cache the results of get_models() for
- themselves once it is safe to do so.
- """
- return self.loaded
-
- def get_apps(self):
- """
- Returns a list of all installed modules that contain models.
- """
- self._populate()
-
- apps = self.app_store.items()
- if self.available_apps is not None:
- apps = [elt for elt in apps
- if self._label_for(elt[0]) in self.available_apps]
-
- # Ensure the returned list is always in the same order (with new apps
- # added at the end). This avoids unstable ordering on the admin app
- # list page, for example.
- apps = sorted(apps, key=lambda elt: elt[1])
-
- return [elt[0] for elt in apps]
-
- def get_app_paths(self):
- """
- Returns a list of paths to all installed apps.
-
- Useful for discovering files at conventional locations inside apps
- (static files, templates, etc.)
- """
- self._populate()
-
- app_paths = []
- for app in self.get_apps():
- if hasattr(app, '__path__'): # models/__init__.py package
- app_paths.extend([upath(path) for path in app.__path__])
- else: # models.py module
- app_paths.append(upath(app.__file__))
- return app_paths
-
- def get_app(self, app_label, emptyOK=False):
- """
- Returns the module containing the models for the given app_label.
-
- Returns None if the app has no models in it and emptyOK is True.
-
- Raises UnavailableApp when set_available_apps() in in effect and
- doesn't include app_label.
- """
- self._populate()
- imp.acquire_lock()
- try:
- for app_name in settings.INSTALLED_APPS:
- if app_label == app_name.split('.')[-1]:
- mod = self.load_app(app_name, False)
- if mod is None and not emptyOK:
- raise ImproperlyConfigured("App with label %s is missing a models.py module." % app_label)
- if self.available_apps is not None and app_label not in self.available_apps:
- raise UnavailableApp("App with label %s isn't available." % app_label)
- return mod
- raise ImproperlyConfigured("App with label %s could not be found" % app_label)
- finally:
- imp.release_lock()
-
- def get_app_errors(self):
- "Returns the map of known problems with the INSTALLED_APPS."
- self._populate()
- return self.app_errors
-
- def get_models(self, app_mod=None,
- include_auto_created=False, include_deferred=False,
- only_installed=True, include_swapped=False):
- """
- Given a module containing models, returns a list of the models.
- Otherwise returns a list of all installed models.
-
- By default, auto-created models (i.e., m2m models without an
- explicit intermediate table) are not included. However, if you
- specify include_auto_created=True, they will be.
-
- By default, models created to satisfy deferred attribute
- queries are *not* included in the list of models. However, if
- you specify include_deferred, they will be.
-
- By default, models that aren't part of installed apps will *not*
- be included in the list of models. However, if you specify
- only_installed=False, they will be.
-
- By default, models that have been swapped out will *not* be
- included in the list of models. However, if you specify
- include_swapped, they will be.
- """
- cache_key = (app_mod, include_auto_created, include_deferred, only_installed, include_swapped)
- model_list = None
- try:
- model_list = self._get_models_cache[cache_key]
- if self.available_apps is not None and only_installed:
- model_list = [m for m in model_list
- if m._meta.app_label in self.available_apps]
- return model_list
- except KeyError:
- pass
- self._populate()
- if app_mod:
- if app_mod in self.app_store:
- app_list = [self.app_models.get(self._label_for(app_mod),
- SortedDict())]
- else:
- app_list = []
- else:
- if only_installed:
- app_list = [self.app_models.get(app_label, SortedDict())
- for app_label in six.iterkeys(self.app_labels)]
- else:
- app_list = six.itervalues(self.app_models)
- model_list = []
- for app in app_list:
- model_list.extend(
- model for model in app.values()
- if ((not model._deferred or include_deferred) and
- (not model._meta.auto_created or include_auto_created) and
- (not model._meta.swapped or include_swapped))
- )
- self._get_models_cache[cache_key] = model_list
- if self.available_apps is not None and only_installed:
- model_list = [m for m in model_list
- if m._meta.app_label in self.available_apps]
- return model_list
-
- def get_model(self, app_label, model_name,
- seed_cache=True, only_installed=True):
- """
- Returns the model matching the given app_label and case-insensitive
- model_name.
-
- Returns None if no model is found.
-
- Raises UnavailableApp when set_available_apps() in in effect and
- doesn't include app_label.
- """
- if seed_cache:
- self._populate()
- if only_installed and app_label not in self.app_labels:
- return None
- if (self.available_apps is not None and only_installed
- and app_label not in self.available_apps):
- raise UnavailableApp("App with label %s isn't available." % app_label)
- try:
- return self.app_models[app_label][model_name.lower()]
- except KeyError:
- return None
-
- def register_models(self, app_label, *models):
- """
- Register a set of models as belonging to an app.
- """
- for model in models:
- # Store as 'name: model' pair in a dictionary
- # in the app_models dictionary
- model_name = model._meta.model_name
- model_dict = self.app_models.setdefault(app_label, SortedDict())
- if model_name in model_dict:
- # The same model may be imported via different paths (e.g.
- # appname.models and project.appname.models). We use the source
- # filename as a means to detect identity.
- fname1 = os.path.abspath(upath(sys.modules[model.__module__].__file__))
- fname2 = os.path.abspath(upath(sys.modules[model_dict[model_name].__module__].__file__))
- # Since the filename extension could be .py the first time and
- # .pyc or .pyo the second time, ignore the extension when
- # comparing.
- if os.path.splitext(fname1)[0] == os.path.splitext(fname2)[0]:
- continue
- model_dict[model_name] = model
- self._get_models_cache.clear()
-
- def set_available_apps(self, available):
- if not set(available).issubset(set(settings.INSTALLED_APPS)):
- extra = set(available) - set(settings.INSTALLED_APPS)
- raise ValueError("Available apps isn't a subset of installed "
- "apps, extra apps: " + ", ".join(extra))
- self.available_apps = set(app.rsplit('.', 1)[-1] for app in available)
-
- def unset_available_apps(self):
- self.available_apps = None
-
-cache = AppCache()
-
-# These methods were always module level, so are kept that way for backwards
-# compatibility.
-get_apps = cache.get_apps
-get_app_paths = cache.get_app_paths
-get_app = cache.get_app
-get_app_errors = cache.get_app_errors
-get_models = cache.get_models
-get_model = cache.get_model
-register_models = cache.register_models
-load_app = cache.load_app
-app_cache_ready = cache.app_cache_ready
diff --git a/lib/python2.7/site-packages/django/db/models/manager.py b/lib/python2.7/site-packages/django/db/models/manager.py
deleted file mode 100644
index a1aa79f..0000000
--- a/lib/python2.7/site-packages/django/db/models/manager.py
+++ /dev/null
@@ -1,283 +0,0 @@
-import copy
-from django.db import router
-from django.db.models.query import QuerySet, insert_query, RawQuerySet
-from django.db.models import signals
-from django.db.models.fields import FieldDoesNotExist
-from django.utils import six
-from django.utils.deprecation import RenameMethodsBase
-
-def ensure_default_manager(sender, **kwargs):
- """
- Ensures that a Model subclass contains a default manager and sets the
- _default_manager attribute on the class. Also sets up the _base_manager
- points to a plain Manager instance (which could be the same as
- _default_manager if it's not a subclass of Manager).
- """
- cls = sender
- if cls._meta.abstract:
- setattr(cls, 'objects', AbstractManagerDescriptor(cls))
- return
- elif cls._meta.swapped:
- setattr(cls, 'objects', SwappedManagerDescriptor(cls))
- return
- if not getattr(cls, '_default_manager', None):
- # Create the default manager, if needed.
- try:
- cls._meta.get_field('objects')
- raise ValueError("Model %s must specify a custom Manager, because it has a field named 'objects'" % cls.__name__)
- except FieldDoesNotExist:
- pass
- cls.add_to_class('objects', Manager())
- cls._base_manager = cls.objects
- elif not getattr(cls, '_base_manager', None):
- default_mgr = cls._default_manager.__class__
- if (default_mgr is Manager or
- getattr(default_mgr, "use_for_related_fields", False)):
- cls._base_manager = cls._default_manager
- else:
- # Default manager isn't a plain Manager class, or a suitable
- # replacement, so we walk up the base class hierarchy until we hit
- # something appropriate.
- for base_class in default_mgr.mro()[1:]:
- if (base_class is Manager or
- getattr(base_class, "use_for_related_fields", False)):
- cls.add_to_class('_base_manager', base_class())
- return
- raise AssertionError("Should never get here. Please report a bug, including your model and model manager setup.")
-
-signals.class_prepared.connect(ensure_default_manager)
-
-
-class RenameManagerMethods(RenameMethodsBase):
- renamed_methods = (
- ('get_query_set', 'get_queryset', PendingDeprecationWarning),
- ('get_prefetch_query_set', 'get_prefetch_queryset', PendingDeprecationWarning),
- )
-
-
-class Manager(six.with_metaclass(RenameManagerMethods)):
- # Tracks each time a Manager instance is created. Used to retain order.
- creation_counter = 0
-
- def __init__(self):
- super(Manager, self).__init__()
- self._set_creation_counter()
- self.model = None
- self._inherited = False
- self._db = None
-
- def contribute_to_class(self, model, name):
- # TODO: Use weakref because of possible memory leak / circular reference.
- self.model = model
- # Only contribute the manager if the model is concrete
- if model._meta.abstract:
- setattr(model, name, AbstractManagerDescriptor(model))
- elif model._meta.swapped:
- setattr(model, name, SwappedManagerDescriptor(model))
- else:
- # if not model._meta.abstract and not model._meta.swapped:
- setattr(model, name, ManagerDescriptor(self))
- if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter:
- model._default_manager = self
- if model._meta.abstract or (self._inherited and not self.model._meta.proxy):
- model._meta.abstract_managers.append((self.creation_counter, name,
- self))
- else:
- model._meta.concrete_managers.append((self.creation_counter, name,
- self))
-
- def _set_creation_counter(self):
- """
- Sets the creation counter value for this instance and increments the
- class-level copy.
- """
- self.creation_counter = Manager.creation_counter
- Manager.creation_counter += 1
-
- def _copy_to_model(self, model):
- """
- Makes a copy of the manager and assigns it to 'model', which should be
- a child of the existing model (used when inheriting a manager from an
- abstract base class).
- """
- assert issubclass(model, self.model)
- mgr = copy.copy(self)
- mgr._set_creation_counter()
- mgr.model = model
- mgr._inherited = True
- return mgr
-
- def db_manager(self, using):
- obj = copy.copy(self)
- obj._db = using
- return obj
-
- @property
- def db(self):
- return self._db or router.db_for_read(self.model)
-
- #######################
- # PROXIES TO QUERYSET #
- #######################
-
- def get_queryset(self):
- """Returns a new QuerySet object. Subclasses can override this method
- to easily customize the behavior of the Manager.
- """
- return QuerySet(self.model, using=self._db)
-
- def none(self):
- return self.get_queryset().none()
-
- def all(self):
- return self.get_queryset()
-
- def count(self):
- return self.get_queryset().count()
-
- def dates(self, *args, **kwargs):
- return self.get_queryset().dates(*args, **kwargs)
-
- def datetimes(self, *args, **kwargs):
- return self.get_queryset().datetimes(*args, **kwargs)
-
- def distinct(self, *args, **kwargs):
- return self.get_queryset().distinct(*args, **kwargs)
-
- def extra(self, *args, **kwargs):
- return self.get_queryset().extra(*args, **kwargs)
-
- def get(self, *args, **kwargs):
- return self.get_queryset().get(*args, **kwargs)
-
- def get_or_create(self, **kwargs):
- return self.get_queryset().get_or_create(**kwargs)
-
- def create(self, **kwargs):
- return self.get_queryset().create(**kwargs)
-
- def bulk_create(self, *args, **kwargs):
- return self.get_queryset().bulk_create(*args, **kwargs)
-
- def filter(self, *args, **kwargs):
- return self.get_queryset().filter(*args, **kwargs)
-
- def aggregate(self, *args, **kwargs):
- return self.get_queryset().aggregate(*args, **kwargs)
-
- def annotate(self, *args, **kwargs):
- return self.get_queryset().annotate(*args, **kwargs)
-
- def complex_filter(self, *args, **kwargs):
- return self.get_queryset().complex_filter(*args, **kwargs)
-
- def exclude(self, *args, **kwargs):
- return self.get_queryset().exclude(*args, **kwargs)
-
- def in_bulk(self, *args, **kwargs):
- return self.get_queryset().in_bulk(*args, **kwargs)
-
- def iterator(self, *args, **kwargs):
- return self.get_queryset().iterator(*args, **kwargs)
-
- def earliest(self, *args, **kwargs):
- return self.get_queryset().earliest(*args, **kwargs)
-
- def latest(self, *args, **kwargs):
- return self.get_queryset().latest(*args, **kwargs)
-
- def first(self):
- return self.get_queryset().first()
-
- def last(self):
- return self.get_queryset().last()
-
- def order_by(self, *args, **kwargs):
- return self.get_queryset().order_by(*args, **kwargs)
-
- def select_for_update(self, *args, **kwargs):
- return self.get_queryset().select_for_update(*args, **kwargs)
-
- def select_related(self, *args, **kwargs):
- return self.get_queryset().select_related(*args, **kwargs)
-
- def prefetch_related(self, *args, **kwargs):
- return self.get_queryset().prefetch_related(*args, **kwargs)
-
- def values(self, *args, **kwargs):
- return self.get_queryset().values(*args, **kwargs)
-
- def values_list(self, *args, **kwargs):
- return self.get_queryset().values_list(*args, **kwargs)
-
- def update(self, *args, **kwargs):
- return self.get_queryset().update(*args, **kwargs)
-
- def reverse(self, *args, **kwargs):
- return self.get_queryset().reverse(*args, **kwargs)
-
- def defer(self, *args, **kwargs):
- return self.get_queryset().defer(*args, **kwargs)
-
- def only(self, *args, **kwargs):
- return self.get_queryset().only(*args, **kwargs)
-
- def using(self, *args, **kwargs):
- return self.get_queryset().using(*args, **kwargs)
-
- def exists(self, *args, **kwargs):
- return self.get_queryset().exists(*args, **kwargs)
-
- def _insert(self, objs, fields, **kwargs):
- return insert_query(self.model, objs, fields, **kwargs)
-
- def _update(self, values, **kwargs):
- return self.get_queryset()._update(values, **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)
-
-
-class ManagerDescriptor(object):
- # This class ensures managers aren't accessible via model instances.
- # For example, Poll.objects works, but poll_obj.objects raises AttributeError.
- def __init__(self, manager):
- self.manager = manager
-
- def __get__(self, instance, type=None):
- if instance != None:
- raise AttributeError("Manager isn't accessible via %s instances" % type.__name__)
- return self.manager
-
-
-class AbstractManagerDescriptor(object):
- # This class provides a better error message when you try to access a
- # manager on an abstract model.
- def __init__(self, model):
- self.model = model
-
- def __get__(self, instance, type=None):
- raise AttributeError("Manager isn't available; %s is abstract" % (
- self.model._meta.object_name,
- ))
-
-
-class SwappedManagerDescriptor(object):
- # This class provides a better error message when you try to access a
- # manager on a swapped model.
- def __init__(self, model):
- self.model = model
-
- def __get__(self, instance, type=None):
- raise AttributeError("Manager isn't available; %s has been swapped for '%s'" % (
- self.model._meta.object_name, self.model._meta.swapped
- ))
-
-
-class EmptyManager(Manager):
- def __init__(self, model):
- super(EmptyManager, self).__init__()
- self.model = model
-
- def get_queryset(self):
- return super(EmptyManager, self).get_queryset().none()
diff --git a/lib/python2.7/site-packages/django/db/models/options.py b/lib/python2.7/site-packages/django/db/models/options.py
deleted file mode 100644
index 6ccc67d..0000000
--- a/lib/python2.7/site-packages/django/db/models/options.py
+++ /dev/null
@@ -1,589 +0,0 @@
-from __future__ import unicode_literals
-
-import re
-from bisect import bisect
-import warnings
-
-from django.conf import settings
-from django.db.models.fields.related import ManyToManyRel
-from django.db.models.fields import AutoField, FieldDoesNotExist
-from django.db.models.fields.proxy import OrderWrt
-from django.db.models.loading import get_models, app_cache_ready
-from django.utils import six
-from django.utils.functional import cached_property
-from django.utils.datastructures import SortedDict
-from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
-from django.utils.translation import activate, deactivate_all, get_language, string_concat
-
-# Calculate the verbose_name by converting from InitialCaps to "lowercase with spaces".
-get_verbose_name = lambda class_name: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', class_name).lower().strip()
-
-DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering',
- 'unique_together', 'permissions', 'get_latest_by',
- 'order_with_respect_to', 'app_label', 'db_tablespace',
- 'abstract', 'managed', 'proxy', 'swappable', 'auto_created',
- 'index_together', 'select_on_save')
-
-
-@python_2_unicode_compatible
-class Options(object):
- def __init__(self, meta, app_label=None):
- self.local_fields, self.local_many_to_many = [], []
- self.virtual_fields = []
- self.model_name, self.verbose_name = None, None
- self.verbose_name_plural = None
- self.db_table = ''
- self.ordering = []
- self.unique_together = []
- self.index_together = []
- self.select_on_save = False
- self.permissions = []
- self.object_name, self.app_label = None, app_label
- self.get_latest_by = None
- self.order_with_respect_to = None
- self.db_tablespace = settings.DEFAULT_TABLESPACE
- self.meta = meta
- self.pk = None
- self.has_auto_field, self.auto_field = False, None
- self.abstract = False
- self.managed = True
- self.proxy = False
- # For any class that is a proxy (including automatically created
- # classes for deferred object loading), proxy_for_model tells us
- # which class this model is proxying. Note that proxy_for_model
- # can create a chain of proxy models. For non-proxy models, the
- # variable is always None.
- self.proxy_for_model = None
- # For any non-abstract class, the concrete class is the model
- # in the end of the proxy_for_model chain. In particular, for
- # concrete models, the concrete_model is always the class itself.
- self.concrete_model = None
- self.swappable = None
- self.parents = SortedDict()
- self.auto_created = False
-
- # To handle various inheritance situations, we need to track where
- # managers came from (concrete or abstract base classes).
- self.abstract_managers = []
- self.concrete_managers = []
-
- # List of all lookups defined in ForeignKey 'limit_choices_to' options
- # from *other* models. Needed for some admin checks. Internal use only.
- self.related_fkey_lookups = []
-
- def contribute_to_class(self, cls, name):
- from django.db import connection
- from django.db.backends.util import truncate_name
-
- cls._meta = self
- self.model = cls
- self.installed = re.sub('\.models$', '', cls.__module__) in settings.INSTALLED_APPS
- # First, construct the default values for these options.
- self.object_name = cls.__name__
- self.model_name = self.object_name.lower()
- self.verbose_name = get_verbose_name(self.object_name)
-
- # Next, apply any overridden values from 'class Meta'.
- if self.meta:
- meta_attrs = self.meta.__dict__.copy()
- for name in self.meta.__dict__:
- # Ignore any private attributes that Django doesn't care about.
- # NOTE: We can't modify a dictionary's contents while looping
- # over it, so we loop over the *original* dictionary instead.
- if name.startswith('_'):
- del meta_attrs[name]
- for attr_name in DEFAULT_NAMES:
- if attr_name in meta_attrs:
- setattr(self, attr_name, meta_attrs.pop(attr_name))
- elif hasattr(self.meta, attr_name):
- setattr(self, attr_name, getattr(self.meta, attr_name))
-
- # unique_together can be either a tuple of tuples, or a single
- # tuple of two strings. Normalize it to a tuple of tuples, so that
- # calling code can uniformly expect that.
- ut = meta_attrs.pop('unique_together', self.unique_together)
- if ut and not isinstance(ut[0], (tuple, list)):
- ut = (ut,)
- self.unique_together = ut
-
- # verbose_name_plural is a special case because it uses a 's'
- # by default.
- if self.verbose_name_plural is None:
- self.verbose_name_plural = string_concat(self.verbose_name, 's')
-
- # Any leftover attributes must be invalid.
- if meta_attrs != {}:
- raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()))
- else:
- self.verbose_name_plural = string_concat(self.verbose_name, 's')
- del self.meta
-
- # If the db_table wasn't provided, use the app_label + model_name.
- if not self.db_table:
- self.db_table = "%s_%s" % (self.app_label, self.model_name)
- self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
-
- @property
- def module_name(self):
- """
- This property has been deprecated in favor of `model_name`. refs #19689
- """
- warnings.warn(
- "Options.module_name has been deprecated in favor of model_name",
- PendingDeprecationWarning, stacklevel=2)
- return self.model_name
-
- def _prepare(self, model):
- if self.order_with_respect_to:
- self.order_with_respect_to = self.get_field(self.order_with_respect_to)
- self.ordering = ('_order',)
- model.add_to_class('_order', OrderWrt())
- else:
- self.order_with_respect_to = None
-
- if self.pk is None:
- if self.parents:
- # Promote the first parent link in lieu of adding yet another
- # field.
- field = next(six.itervalues(self.parents))
- # Look for a local field with the same name as the
- # first parent link. If a local field has already been
- # created, use it instead of promoting the parent
- already_created = [fld for fld in self.local_fields if fld.name == field.name]
- if already_created:
- field = already_created[0]
- field.primary_key = True
- self.setup_pk(field)
- else:
- auto = AutoField(verbose_name='ID', primary_key=True,
- auto_created=True)
- model.add_to_class('id', auto)
-
- def add_field(self, field):
- # Insert the given field in the order in which it was created, using
- # the "creation_counter" attribute of the field.
- # Move many-to-many related fields from self.fields into
- # self.many_to_many.
- if field.rel and isinstance(field.rel, ManyToManyRel):
- self.local_many_to_many.insert(bisect(self.local_many_to_many, field), field)
- if hasattr(self, '_m2m_cache'):
- del self._m2m_cache
- else:
- self.local_fields.insert(bisect(self.local_fields, field), field)
- self.setup_pk(field)
- if hasattr(self, '_field_cache'):
- del self._field_cache
- del self._field_name_cache
- # The fields, concrete_fields and local_concrete_fields are
- # implemented as cached properties for performance reasons.
- # The attrs will not exists if the cached property isn't
- # accessed yet, hence the try-excepts.
- try:
- del self.fields
- except AttributeError:
- pass
- try:
- del self.concrete_fields
- except AttributeError:
- pass
- try:
- del self.local_concrete_fields
- except AttributeError:
- pass
-
- if hasattr(self, '_name_map'):
- del self._name_map
-
- def add_virtual_field(self, field):
- self.virtual_fields.append(field)
-
- def setup_pk(self, field):
- if not self.pk and field.primary_key:
- self.pk = field
- field.serialize = False
-
- def pk_index(self):
- """
- Returns the index of the primary key field in the self.concrete_fields
- list.
- """
- return self.concrete_fields.index(self.pk)
-
- def setup_proxy(self, target):
- """
- Does the internal setup so that the current model is a proxy for
- "target".
- """
- self.pk = target._meta.pk
- self.proxy_for_model = target
- self.db_table = target._meta.db_table
-
- def __repr__(self):
- return '<Options for %s>' % self.object_name
-
- def __str__(self):
- return "%s.%s" % (smart_text(self.app_label), smart_text(self.model_name))
-
- def verbose_name_raw(self):
- """
- There are a few places where the untranslated verbose name is needed
- (so that we get the same value regardless of currently active
- locale).
- """
- lang = get_language()
- deactivate_all()
- raw = force_text(self.verbose_name)
- activate(lang)
- return raw
- verbose_name_raw = property(verbose_name_raw)
-
- def _swapped(self):
- """
- Has this model been swapped out for another? If so, return the model
- name of the replacement; otherwise, return None.
-
- For historical reasons, model name lookups using get_model() are
- case insensitive, so we make sure we are case insensitive here.
- """
- if self.swappable:
- model_label = '%s.%s' % (self.app_label, self.model_name)
- swapped_for = getattr(settings, self.swappable, None)
- if swapped_for:
- try:
- swapped_label, swapped_object = swapped_for.split('.')
- except ValueError:
- # setting not in the format app_label.model_name
- # raising ImproperlyConfigured here causes problems with
- # test cleanup code - instead it is raised in get_user_model
- # or as part of validation.
- return swapped_for
-
- if '%s.%s' % (swapped_label, swapped_object.lower()) not in (None, model_label):
- return swapped_for
- return None
- swapped = property(_swapped)
-
- @cached_property
- def fields(self):
- """
- The getter for self.fields. This returns the list of field objects
- available to this model (including through parent models).
-
- Callers are not permitted to modify this list, since it's a reference
- to this instance (not a copy).
- """
- try:
- self._field_name_cache
- except AttributeError:
- self._fill_fields_cache()
- return self._field_name_cache
-
- @cached_property
- def concrete_fields(self):
- return [f for f in self.fields if f.column is not None]
-
- @cached_property
- def local_concrete_fields(self):
- return [f for f in self.local_fields if f.column is not None]
-
- def get_fields_with_model(self):
- """
- Returns a sequence of (field, model) pairs for all fields. The "model"
- element is None for fields on the current model. Mostly of use when
- constructing queries so that we know which model a field belongs to.
- """
- try:
- self._field_cache
- except AttributeError:
- self._fill_fields_cache()
- return self._field_cache
-
- def get_concrete_fields_with_model(self):
- return [(field, model) for field, model in self.get_fields_with_model() if
- field.column is not None]
-
- def _fill_fields_cache(self):
- cache = []
- for parent in self.parents:
- for field, model in parent._meta.get_fields_with_model():
- if model:
- cache.append((field, model))
- else:
- cache.append((field, parent))
- cache.extend([(f, None) for f in self.local_fields])
- self._field_cache = tuple(cache)
- self._field_name_cache = [x for x, _ in cache]
-
- def _many_to_many(self):
- try:
- self._m2m_cache
- except AttributeError:
- self._fill_m2m_cache()
- return list(self._m2m_cache)
- many_to_many = property(_many_to_many)
-
- def get_m2m_with_model(self):
- """
- The many-to-many version of get_fields_with_model().
- """
- try:
- self._m2m_cache
- except AttributeError:
- self._fill_m2m_cache()
- return list(six.iteritems(self._m2m_cache))
-
- def _fill_m2m_cache(self):
- cache = SortedDict()
- for parent in self.parents:
- for field, model in parent._meta.get_m2m_with_model():
- if model:
- cache[field] = model
- else:
- cache[field] = parent
- for field in self.local_many_to_many:
- cache[field] = None
- self._m2m_cache = cache
-
- def get_field(self, name, many_to_many=True):
- """
- Returns the requested field by name. Raises FieldDoesNotExist on error.
- """
- to_search = (self.fields + self.many_to_many) if many_to_many else self.fields
- for f in to_search:
- if f.name == name:
- return f
- raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, name))
-
- def get_field_by_name(self, name):
- """
- Returns the (field_object, model, direct, m2m), where field_object is
- the Field instance for the given name, model is the model containing
- this field (None for local fields), direct is True if the field exists
- on this model, and m2m is True for many-to-many relations. When
- 'direct' is False, 'field_object' is the corresponding RelatedObject
- for this field (since the field doesn't have an instance associated
- with it).
-
- Uses a cache internally, so after the first access, this is very fast.
- """
- try:
- try:
- return self._name_map[name]
- except AttributeError:
- cache = self.init_name_map()
- return cache[name]
- except KeyError:
- raise FieldDoesNotExist('%s has no field named %r'
- % (self.object_name, name))
-
- def get_all_field_names(self):
- """
- Returns a list of all field names that are possible for this model
- (including reverse relation names). This is used for pretty printing
- debugging output (a list of choices), so any internal-only field names
- are not included.
- """
- try:
- cache = self._name_map
- except AttributeError:
- cache = self.init_name_map()
- names = sorted(cache.keys())
- # Internal-only names end with "+" (symmetrical m2m related names being
- # the main example). Trim them.
- return [val for val in names if not val.endswith('+')]
-
- def init_name_map(self):
- """
- Initialises the field name -> field object mapping.
- """
- cache = {}
- # We intentionally handle related m2m objects first so that symmetrical
- # m2m accessor names can be overridden, if necessary.
- for f, model in self.get_all_related_m2m_objects_with_model():
- cache[f.field.related_query_name()] = (f, model, False, True)
- for f, model in self.get_all_related_objects_with_model():
- cache[f.field.related_query_name()] = (f, model, False, False)
- for f, model in self.get_m2m_with_model():
- cache[f.name] = (f, model, True, True)
- for f, model in self.get_fields_with_model():
- cache[f.name] = (f, model, True, False)
- for f in self.virtual_fields:
- if hasattr(f, 'related'):
- cache[f.name] = (f.related, None if f.model == self.model else f.model, True, False)
- if app_cache_ready():
- self._name_map = cache
- return cache
-
- def get_add_permission(self):
- """
- This method has been deprecated in favor of
- `django.contrib.auth.get_permission_codename`. refs #20642
- """
- warnings.warn(
- "`Options.get_add_permission` has been deprecated in favor "
- "of `django.contrib.auth.get_permission_codename`.",
- PendingDeprecationWarning, stacklevel=2)
- return 'add_%s' % self.model_name
-
- def get_change_permission(self):
- """
- This method has been deprecated in favor of
- `django.contrib.auth.get_permission_codename`. refs #20642
- """
- warnings.warn(
- "`Options.get_change_permission` has been deprecated in favor "
- "of `django.contrib.auth.get_permission_codename`.",
- PendingDeprecationWarning, stacklevel=2)
- return 'change_%s' % self.model_name
-
- def get_delete_permission(self):
- """
- This method has been deprecated in favor of
- `django.contrib.auth.get_permission_codename`. refs #20642
- """
- warnings.warn(
- "`Options.get_delete_permission` has been deprecated in favor "
- "of `django.contrib.auth.get_permission_codename`.",
- PendingDeprecationWarning, stacklevel=2)
- return 'delete_%s' % self.model_name
-
- def get_all_related_objects(self, local_only=False, include_hidden=False,
- include_proxy_eq=False):
- return [k for k, v in self.get_all_related_objects_with_model(
- local_only=local_only, include_hidden=include_hidden,
- include_proxy_eq=include_proxy_eq)]
-
- def get_all_related_objects_with_model(self, local_only=False,
- include_hidden=False,
- include_proxy_eq=False):
- """
- Returns a list of (related-object, model) pairs. Similar to
- get_fields_with_model().
- """
- try:
- self._related_objects_cache
- except AttributeError:
- self._fill_related_objects_cache()
- predicates = []
- if local_only:
- predicates.append(lambda k, v: not v)
- if not include_hidden:
- predicates.append(lambda k, v: not k.field.rel.is_hidden())
- cache = (self._related_objects_proxy_cache if include_proxy_eq
- else self._related_objects_cache)
- return [t for t in cache.items() if all(p(*t) for p in predicates)]
-
- def _fill_related_objects_cache(self):
- cache = SortedDict()
- parent_list = self.get_parent_list()
- for parent in self.parents:
- for obj, model in parent._meta.get_all_related_objects_with_model(include_hidden=True):
- if (obj.field.creation_counter < 0 or obj.field.rel.parent_link) and obj.model not in parent_list:
- continue
- if not model:
- cache[obj] = parent
- else:
- cache[obj] = model
- # Collect also objects which are in relation to some proxy child/parent of self.
- proxy_cache = cache.copy()
- for klass in get_models(include_auto_created=True, only_installed=False):
- if not klass._meta.swapped:
- for f in klass._meta.local_fields:
- if f.rel and not isinstance(f.rel.to, six.string_types) and f.generate_reverse_relation:
- if self == f.rel.to._meta:
- cache[f.related] = None
- proxy_cache[f.related] = None
- elif self.concrete_model == f.rel.to._meta.concrete_model:
- proxy_cache[f.related] = None
- self._related_objects_cache = cache
- self._related_objects_proxy_cache = proxy_cache
-
- def get_all_related_many_to_many_objects(self, local_only=False):
- try:
- cache = self._related_many_to_many_cache
- except AttributeError:
- cache = self._fill_related_many_to_many_cache()
- if local_only:
- return [k for k, v in cache.items() if not v]
- return list(cache)
-
- def get_all_related_m2m_objects_with_model(self):
- """
- Returns a list of (related-m2m-object, model) pairs. Similar to
- get_fields_with_model().
- """
- try:
- cache = self._related_many_to_many_cache
- except AttributeError:
- cache = self._fill_related_many_to_many_cache()
- return list(six.iteritems(cache))
-
- def _fill_related_many_to_many_cache(self):
- cache = SortedDict()
- parent_list = self.get_parent_list()
- for parent in self.parents:
- for obj, model in parent._meta.get_all_related_m2m_objects_with_model():
- if obj.field.creation_counter < 0 and obj.model not in parent_list:
- continue
- if not model:
- cache[obj] = parent
- else:
- cache[obj] = model
- for klass in get_models(only_installed=False):
- if not klass._meta.swapped:
- for f in klass._meta.local_many_to_many:
- if (f.rel
- and not isinstance(f.rel.to, six.string_types)
- and self == f.rel.to._meta):
- cache[f.related] = None
- if app_cache_ready():
- self._related_many_to_many_cache = cache
- return cache
-
- def get_base_chain(self, model):
- """
- Returns a list of parent classes leading to 'model' (order from closet
- to most distant ancestor). This has to handle the case were 'model' is
- a granparent or even more distant relation.
- """
- if not self.parents:
- return None
- if model in self.parents:
- return [model]
- for parent in self.parents:
- res = parent._meta.get_base_chain(model)
- if res:
- res.insert(0, parent)
- return res
- return None
-
- def get_parent_list(self):
- """
- Returns a list of all the ancestor of this model as a list. Useful for
- determining if something is an ancestor, regardless of lineage.
- """
- result = set()
- for parent in self.parents:
- result.add(parent)
- result.update(parent._meta.get_parent_list())
- return result
-
- def get_ancestor_link(self, ancestor):
- """
- Returns the field on the current model which points to the given
- "ancestor". This is possible an indirect link (a pointer to a parent
- model, which points, eventually, to the ancestor). Used when
- constructing table joins for model inheritance.
-
- Returns None if the model isn't an ancestor of this one.
- """
- if ancestor in self.parents:
- return self.parents[ancestor]
- for parent in self.parents:
- # Tries to get a link field from the immediate parent
- parent_link = parent._meta.get_ancestor_link(ancestor)
- if parent_link:
- # In case of a proxied model, the first link
- # of the chain to the ancestor is that parent
- # links
- return self.parents[parent] or parent_link
diff --git a/lib/python2.7/site-packages/django/db/models/query.py b/lib/python2.7/site-packages/django/db/models/query.py
deleted file mode 100644
index 44047d4..0000000
--- a/lib/python2.7/site-packages/django/db/models/query.py
+++ /dev/null
@@ -1,1731 +0,0 @@
-"""
-The main QuerySet implementation. This provides the public API for the ORM.
-"""
-
-import copy
-import itertools
-import sys
-import warnings
-
-from django.conf import settings
-from django.core import exceptions
-from django.db import connections, router, transaction, DatabaseError
-from django.db.models.constants import LOOKUP_SEP
-from django.db.models.fields import AutoField
-from django.db.models.query_utils import (Q, select_related_descend,
- deferred_class_factory, InvalidQuery)
-from django.db.models.deletion import Collector
-from django.db.models import sql
-from django.utils.functional import partition
-from django.utils import six
-from django.utils import timezone
-
-# The maximum number of items to display in a QuerySet.__repr__
-REPR_OUTPUT_SIZE = 20
-
-# Pull into this namespace for backwards compatibility.
-EmptyResultSet = sql.EmptyResultSet
-
-
-class QuerySet(object):
- """
- Represents a lazy database lookup for a set of objects.
- """
- def __init__(self, model=None, query=None, using=None):
- self.model = model
- self._db = using
- self.query = query or sql.Query(self.model)
- self._result_cache = None
- self._sticky_filter = False
- self._for_write = False
- self._prefetch_related_lookups = []
- self._prefetch_done = False
- self._known_related_objects = {} # {rel_field, {pk: rel_obj}}
-
- ########################
- # PYTHON MAGIC METHODS #
- ########################
-
- def __deepcopy__(self, memo):
- """
- Deep copy of a QuerySet doesn't populate the cache
- """
- obj = self.__class__()
- for k, v in self.__dict__.items():
- if k == '_result_cache':
- obj.__dict__[k] = None
- else:
- obj.__dict__[k] = copy.deepcopy(v, memo)
- return obj
-
- def __getstate__(self):
- """
- Allows the QuerySet to be pickled.
- """
- # Force the cache to be fully populated.
- self._fetch_all()
- obj_dict = self.__dict__.copy()
- return obj_dict
-
- def __repr__(self):
- data = list(self[:REPR_OUTPUT_SIZE + 1])
- if len(data) > REPR_OUTPUT_SIZE:
- data[-1] = "...(remaining elements truncated)..."
- return repr(data)
-
- def __len__(self):
- self._fetch_all()
- return len(self._result_cache)
-
- def __iter__(self):
- """
- The queryset iterator protocol uses three nested iterators in the
- default case:
- 1. sql.compiler:execute_sql()
- - Returns 100 rows at time (constants.GET_ITERATOR_CHUNK_SIZE)
- using cursor.fetchmany(). This part is responsible for
- doing some column masking, and returning the rows in chunks.
- 2. sql/compiler.results_iter()
- - Returns one row at time. At this point the rows are still just
- tuples. In some cases the return values are converted to
- Python values at this location (see resolve_columns(),
- resolve_aggregate()).
- 3. self.iterator()
- - Responsible for turning the rows into model objects.
- """
- self._fetch_all()
- return iter(self._result_cache)
-
- def __nonzero__(self):
- self._fetch_all()
- return bool(self._result_cache)
-
- def __getitem__(self, k):
- """
- Retrieves an item or slice from the set of results.
- """
- if not isinstance(k, (slice,) + six.integer_types):
- raise TypeError
- assert ((not isinstance(k, slice) and (k >= 0))
- or (isinstance(k, slice) and (k.start is None or k.start >= 0)
- and (k.stop is None or k.stop >= 0))), \
- "Negative indexing is not supported."
-
- if self._result_cache is not None:
- return self._result_cache[k]
-
- if isinstance(k, slice):
- qs = self._clone()
- if k.start is not None:
- start = int(k.start)
- else:
- start = None
- if k.stop is not None:
- stop = int(k.stop)
- else:
- stop = None
- qs.query.set_limits(start, stop)
- return list(qs)[::k.step] if k.step else qs
-
- qs = self._clone()
- qs.query.set_limits(k, k + 1)
- return list(qs)[0]
-
- def __and__(self, other):
- self._merge_sanity_check(other)
- if isinstance(other, EmptyQuerySet):
- return other
- if isinstance(self, EmptyQuerySet):
- return self
- combined = self._clone()
- combined._merge_known_related_objects(other)
- combined.query.combine(other.query, sql.AND)
- return combined
-
- def __or__(self, other):
- self._merge_sanity_check(other)
- if isinstance(self, EmptyQuerySet):
- return other
- if isinstance(other, EmptyQuerySet):
- return self
- combined = self._clone()
- combined._merge_known_related_objects(other)
- combined.query.combine(other.query, sql.OR)
- return combined
-
- ####################################
- # METHODS THAT DO DATABASE QUERIES #
- ####################################
-
- def iterator(self):
- """
- An iterator over the results from applying this QuerySet to the
- database.
- """
- fill_cache = False
- if connections[self.db].features.supports_select_related:
- fill_cache = self.query.select_related
- if isinstance(fill_cache, dict):
- requested = fill_cache
- else:
- requested = None
- max_depth = self.query.max_depth
-
- extra_select = list(self.query.extra_select)
- aggregate_select = list(self.query.aggregate_select)
-
- only_load = self.query.get_loaded_field_names()
- if not fill_cache:
- fields = self.model._meta.concrete_fields
-
- load_fields = []
- # If only/defer clauses have been specified,
- # build the list of fields that are to be loaded.
- if only_load:
- for field, model in self.model._meta.get_concrete_fields_with_model():
- if model is None:
- model = self.model
- try:
- if field.name in only_load[model]:
- # Add a field that has been explicitly included
- load_fields.append(field.name)
- except KeyError:
- # Model wasn't explicitly listed in the only_load table
- # Therefore, we need to load all fields from this model
- load_fields.append(field.name)
-
- index_start = len(extra_select)
- aggregate_start = index_start + len(load_fields or self.model._meta.concrete_fields)
-
- skip = None
- if load_fields and not fill_cache:
- # Some fields have been deferred, so we have to initialise
- # via keyword arguments.
- skip = set()
- init_list = []
- for field in fields:
- if field.name not in load_fields:
- skip.add(field.attname)
- else:
- init_list.append(field.attname)
- model_cls = deferred_class_factory(self.model, skip)
-
- # Cache db and model outside the loop
- db = self.db
- model = self.model
- compiler = self.query.get_compiler(using=db)
- if fill_cache:
- klass_info = get_klass_info(model, max_depth=max_depth,
- requested=requested, only_load=only_load)
- for row in compiler.results_iter():
- if fill_cache:
- obj, _ = get_cached_row(row, index_start, db, klass_info,
- offset=len(aggregate_select))
- else:
- # Omit aggregates in object creation.
- row_data = row[index_start:aggregate_start]
- if skip:
- obj = model_cls(**dict(zip(init_list, row_data)))
- else:
- obj = model(*row_data)
-
- # Store the source database of the object
- obj._state.db = db
- # This object came from the database; it's not being added.
- obj._state.adding = False
-
- if extra_select:
- for i, k in enumerate(extra_select):
- setattr(obj, k, row[i])
-
- # Add the aggregates to the model
- if aggregate_select:
- for i, aggregate in enumerate(aggregate_select):
- setattr(obj, aggregate, row[i + aggregate_start])
-
- # Add the known related objects to the model, if there are any
- if self._known_related_objects:
- for field, rel_objs in self._known_related_objects.items():
- pk = getattr(obj, field.get_attname())
- try:
- rel_obj = rel_objs[pk]
- except KeyError:
- pass # may happen in qs1 | qs2 scenarios
- else:
- setattr(obj, field.name, rel_obj)
-
- yield obj
-
- def aggregate(self, *args, **kwargs):
- """
- Returns a dictionary containing the calculations (aggregation)
- over the current queryset
-
- If args is present the expression is passed as a kwarg using
- the Aggregate object's default alias.
- """
- if self.query.distinct_fields:
- raise NotImplementedError("aggregate() + distinct(fields) not implemented.")
- for arg in args:
- kwargs[arg.default_alias] = arg
-
- query = self.query.clone()
-
- for (alias, aggregate_expr) in kwargs.items():
- query.add_aggregate(aggregate_expr, self.model, alias,
- is_summary=True)
-
- return query.get_aggregation(using=self.db)
-
- def count(self):
- """
- Performs a SELECT COUNT() and returns the number of records as an
- integer.
-
- If the QuerySet is already fully cached this simply returns the length
- of the cached results set to avoid multiple SELECT COUNT(*) calls.
- """
- if self._result_cache is not None:
- return len(self._result_cache)
-
- return self.query.get_count(using=self.db)
-
- def get(self, *args, **kwargs):
- """
- Performs the query and returns a single object matching the given
- keyword arguments.
- """
- clone = self.filter(*args, **kwargs)
- if self.query.can_filter():
- clone = clone.order_by()
- num = len(clone)
- if num == 1:
- return clone._result_cache[0]
- if not num:
- raise self.model.DoesNotExist(
- "%s matching query does not exist." %
- self.model._meta.object_name)
- raise self.model.MultipleObjectsReturned(
- "get() returned more than one %s -- it returned %s!" %
- (self.model._meta.object_name, num))
-
- def create(self, **kwargs):
- """
- Creates a new object with the given kwargs, saving it to the database
- and returning the created object.
- """
- obj = self.model(**kwargs)
- self._for_write = True
- obj.save(force_insert=True, using=self.db)
- return obj
-
- def bulk_create(self, objs, batch_size=None):
- """
- Inserts each of the instances into the database. This does *not* call
- save() on each of the instances, does not send any pre/post save
- signals, and does not set the primary key attribute if it is an
- autoincrement field.
- """
- # So this case is fun. When you bulk insert you don't get the primary
- # keys back (if it's an autoincrement), so you can't insert into the
- # child tables which references this. There are two workarounds, 1)
- # this could be implemented if you didn't have an autoincrement pk,
- # and 2) you could do it by doing O(n) normal inserts into the parent
- # tables to get the primary keys back, and then doing a single bulk
- # insert into the childmost table. Some databases might allow doing
- # this by using RETURNING clause for the insert query. We're punting
- # on these for now because they are relatively rare cases.
- assert batch_size is None or batch_size > 0
- if self.model._meta.parents:
- raise ValueError("Can't bulk create an inherited model")
- if not objs:
- return objs
- self._for_write = True
- connection = connections[self.db]
- fields = self.model._meta.local_concrete_fields
- with transaction.commit_on_success_unless_managed(using=self.db):
- if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk
- and self.model._meta.has_auto_field):
- self._batched_insert(objs, fields, batch_size)
- else:
- objs_with_pk, objs_without_pk = partition(lambda o: o.pk is None, objs)
- if objs_with_pk:
- self._batched_insert(objs_with_pk, fields, batch_size)
- if objs_without_pk:
- fields= [f for f in fields if not isinstance(f, AutoField)]
- self._batched_insert(objs_without_pk, fields, batch_size)
-
- return objs
-
- def get_or_create(self, **kwargs):
- """
- Looks up an object with the given kwargs, creating one if necessary.
- Returns a tuple of (object, created), where created is a boolean
- specifying whether an object was created.
- """
- defaults = kwargs.pop('defaults', {})
- lookup = kwargs.copy()
- for f in self.model._meta.fields:
- if f.attname in lookup:
- lookup[f.name] = lookup.pop(f.attname)
- try:
- self._for_write = True
- return self.get(**lookup), False
- except self.model.DoesNotExist:
- try:
- params = dict((k, v) for k, v in kwargs.items() if LOOKUP_SEP not in k)
- params.update(defaults)
- obj = self.model(**params)
- with transaction.atomic(using=self.db):
- obj.save(force_insert=True, using=self.db)
- return obj, True
- except DatabaseError:
- exc_info = sys.exc_info()
- try:
- return self.get(**lookup), False
- except self.model.DoesNotExist:
- # Re-raise the DatabaseError with its original traceback.
- six.reraise(*exc_info)
-
- def _earliest_or_latest(self, field_name=None, direction="-"):
- """
- Returns the latest object, according to the model's
- 'get_latest_by' option or optional given field_name.
- """
- order_by = field_name or getattr(self.model._meta, 'get_latest_by')
- assert bool(order_by), "earliest() and latest() require either a "\
- "field_name parameter or 'get_latest_by' in the model"
- assert self.query.can_filter(), \
- "Cannot change a query once a slice has been taken."
- obj = self._clone()
- obj.query.set_limits(high=1)
- obj.query.clear_ordering(force_empty=True)
- obj.query.add_ordering('%s%s' % (direction, order_by))
- return obj.get()
-
- def earliest(self, field_name=None):
- return self._earliest_or_latest(field_name=field_name, direction="")
-
- def latest(self, field_name=None):
- return self._earliest_or_latest(field_name=field_name, direction="-")
-
- def first(self):
- """
- Returns the first object of a query, returns None if no match is found.
- """
- qs = self if self.ordered else self.order_by('pk')
- try:
- return qs[0]
- except IndexError:
- return None
-
- def last(self):
- """
- Returns the last object of a query, returns None if no match is found.
- """
- qs = self.reverse() if self.ordered else self.order_by('-pk')
- try:
- return qs[0]
- except IndexError:
- return None
-
- def in_bulk(self, id_list):
- """
- Returns a dictionary mapping each of the given IDs to the object with
- that ID.
- """
- assert self.query.can_filter(), \
- "Cannot use 'limit' or 'offset' with in_bulk"
- if not id_list:
- return {}
- qs = self.filter(pk__in=id_list).order_by()
- return dict([(obj._get_pk_val(), obj) for obj in qs])
-
- def delete(self):
- """
- Deletes the records in the current QuerySet.
- """
- assert self.query.can_filter(), \
- "Cannot use 'limit' or 'offset' with delete."
-
- del_query = self._clone()
-
- # The delete is actually 2 queries - one to find related objects,
- # and one to delete. Make sure that the discovery of related
- # objects is performed on the same database as the deletion.
- del_query._for_write = True
-
- # Disable non-supported fields.
- del_query.query.select_for_update = False
- del_query.query.select_related = False
- del_query.query.clear_ordering(force_empty=True)
-
- collector = Collector(using=del_query.db)
- collector.collect(del_query)
- collector.delete()
-
- # Clear the result cache, in case this QuerySet gets reused.
- self._result_cache = None
- delete.alters_data = True
-
- def _raw_delete(self, using):
- """
- Deletes objects found from the given queryset in single direct SQL
- query. No signals are sent, and there is no protection for cascades.
- """
- sql.DeleteQuery(self.model).delete_qs(self, using)
- _raw_delete.alters_data = True
-
- def update(self, **kwargs):
- """
- Updates all elements in the current QuerySet, setting all the given
- fields to the appropriate values.
- """
- assert self.query.can_filter(), \
- "Cannot update a query once a slice has been taken."
- self._for_write = True
- query = self.query.clone(sql.UpdateQuery)
- query.add_update_values(kwargs)
- with transaction.commit_on_success_unless_managed(using=self.db):
- rows = query.get_compiler(self.db).execute_sql(None)
- self._result_cache = None
- return rows
- update.alters_data = True
-
- def _update(self, values):
- """
- A version of update that accepts field objects instead of field names.
- Used primarily for model saving and not intended for use by general
- code (it requires too much poking around at model internals to be
- useful at that level).
- """
- assert self.query.can_filter(), \
- "Cannot update a query once a slice has been taken."
- query = self.query.clone(sql.UpdateQuery)
- query.add_update_fields(values)
- self._result_cache = None
- return query.get_compiler(self.db).execute_sql(None)
- _update.alters_data = True
-
- def exists(self):
- if self._result_cache is None:
- return self.query.has_results(using=self.db)
- return bool(self._result_cache)
-
- def _prefetch_related_objects(self):
- # This method can only be called once the result cache has been filled.
- prefetch_related_objects(self._result_cache, self._prefetch_related_lookups)
- self._prefetch_done = True
-
- ##################################################
- # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
- ##################################################
-
- def values(self, *fields):
- return self._clone(klass=ValuesQuerySet, setup=True, _fields=fields)
-
- def values_list(self, *fields, **kwargs):
- flat = kwargs.pop('flat', False)
- if kwargs:
- raise TypeError('Unexpected keyword arguments to values_list: %s'
- % (list(kwargs),))
- if flat and len(fields) > 1:
- raise TypeError("'flat' is not valid when values_list is called with more than one field.")
- return self._clone(klass=ValuesListQuerySet, setup=True, flat=flat,
- _fields=fields)
-
- def dates(self, field_name, kind, order='ASC'):
- """
- Returns a list of date objects representing all available dates for
- the given field_name, scoped to 'kind'.
- """
- assert kind in ("year", "month", "day"), \
- "'kind' must be one of 'year', 'month' or 'day'."
- assert order in ('ASC', 'DESC'), \
- "'order' must be either 'ASC' or 'DESC'."
- return self._clone(klass=DateQuerySet, setup=True,
- _field_name=field_name, _kind=kind, _order=order)
-
- def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
- """
- Returns a list of datetime objects representing all available
- datetimes for the given field_name, scoped to 'kind'.
- """
- assert kind in ("year", "month", "day", "hour", "minute", "second"), \
- "'kind' must be one of 'year', 'month', 'day', 'hour', 'minute' or 'second'."
- assert order in ('ASC', 'DESC'), \
- "'order' must be either 'ASC' or 'DESC'."
- if settings.USE_TZ:
- if tzinfo is None:
- tzinfo = timezone.get_current_timezone()
- else:
- tzinfo = None
- return self._clone(klass=DateTimeQuerySet, setup=True,
- _field_name=field_name, _kind=kind, _order=order, _tzinfo=tzinfo)
-
- def none(self):
- """
- Returns an empty QuerySet.
- """
- clone = self._clone()
- clone.query.set_empty()
- return clone
-
- ##################################################################
- # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
- ##################################################################
-
- def all(self):
- """
- Returns a new QuerySet that is a copy of the current one. This allows a
- QuerySet to proxy for a model manager in some cases.
- """
- return self._clone()
-
- def filter(self, *args, **kwargs):
- """
- Returns a new QuerySet instance with the args ANDed to the existing
- set.
- """
- return self._filter_or_exclude(False, *args, **kwargs)
-
- def exclude(self, *args, **kwargs):
- """
- Returns a new QuerySet instance with NOT (args) ANDed to the existing
- set.
- """
- return self._filter_or_exclude(True, *args, **kwargs)
-
- def _filter_or_exclude(self, negate, *args, **kwargs):
- if args or kwargs:
- assert self.query.can_filter(), \
- "Cannot filter a query once a slice has been taken."
-
- clone = self._clone()
- if negate:
- clone.query.add_q(~Q(*args, **kwargs))
- else:
- clone.query.add_q(Q(*args, **kwargs))
- return clone
-
- def complex_filter(self, filter_obj):
- """
- Returns a new QuerySet instance with filter_obj added to the filters.
-
- filter_obj can be a Q object (or anything with an add_to_query()
- method) or a dictionary of keyword lookup arguments.
-
- This exists to support framework features such as 'limit_choices_to',
- and usually it will be more natural to use other methods.
- """
- if isinstance(filter_obj, Q) or hasattr(filter_obj, 'add_to_query'):
- clone = self._clone()
- clone.query.add_q(filter_obj)
- return clone
- else:
- return self._filter_or_exclude(None, **filter_obj)
-
- def select_for_update(self, **kwargs):
- """
- Returns a new QuerySet instance that will select objects with a
- FOR UPDATE lock.
- """
- # Default to false for nowait
- nowait = kwargs.pop('nowait', False)
- obj = self._clone()
- obj._for_write = True
- obj.query.select_for_update = True
- obj.query.select_for_update_nowait = nowait
- return obj
-
- def select_related(self, *fields, **kwargs):
- """
- Returns a new QuerySet instance that will select related objects.
-
- If fields are specified, they must be ForeignKey fields and only those
- related objects are included in the selection.
-
- If select_related(None) is called, the list is cleared.
- """
- if 'depth' in kwargs:
- warnings.warn('The "depth" keyword argument has been deprecated.\n'
- 'Use related field names instead.', DeprecationWarning, stacklevel=2)
- depth = kwargs.pop('depth', 0)
- if kwargs:
- raise TypeError('Unexpected keyword arguments to select_related: %s'
- % (list(kwargs),))
- obj = self._clone()
- if fields == (None,):
- obj.query.select_related = False
- elif fields:
- if depth:
- raise TypeError('Cannot pass both "depth" and fields to select_related()')
- obj.query.add_select_related(fields)
- else:
- obj.query.select_related = True
- if depth:
- obj.query.max_depth = depth
- return obj
-
- def prefetch_related(self, *lookups):
- """
- Returns a new QuerySet instance that will prefetch the specified
- Many-To-One and Many-To-Many related objects when the QuerySet is
- evaluated.
-
- When prefetch_related() is called more than once, the list of lookups to
- prefetch is appended to. If prefetch_related(None) is called, the
- the list is cleared.
- """
- clone = self._clone()
- if lookups == (None,):
- clone._prefetch_related_lookups = []
- else:
- clone._prefetch_related_lookups.extend(lookups)
- return clone
-
- def annotate(self, *args, **kwargs):
- """
- Return a query set in which the returned objects have been annotated
- with data aggregated from related fields.
- """
- for arg in args:
- if arg.default_alias in kwargs:
- raise ValueError("The named annotation '%s' conflicts with the "
- "default name for another annotation."
- % arg.default_alias)
- kwargs[arg.default_alias] = arg
-
- names = getattr(self, '_fields', None)
- if names is None:
- names = set(self.model._meta.get_all_field_names())
- for aggregate in kwargs:
- if aggregate in names:
- raise ValueError("The annotation '%s' conflicts with a field on "
- "the model." % aggregate)
-
- obj = self._clone()
-
- obj._setup_aggregate_query(list(kwargs))
-
- # Add the aggregates to the query
- for (alias, aggregate_expr) in kwargs.items():
- obj.query.add_aggregate(aggregate_expr, self.model, alias,
- is_summary=False)
-
- return obj
-
- def order_by(self, *field_names):
- """
- Returns a new QuerySet instance with the ordering changed.
- """
- assert self.query.can_filter(), \
- "Cannot reorder a query once a slice has been taken."
- obj = self._clone()
- obj.query.clear_ordering(force_empty=False)
- obj.query.add_ordering(*field_names)
- return obj
-
- def distinct(self, *field_names):
- """
- Returns a new QuerySet instance that will select only distinct results.
- """
- assert self.query.can_filter(), \
- "Cannot create distinct fields once a slice has been taken."
- obj = self._clone()
- obj.query.add_distinct_fields(*field_names)
- return obj
-
- def extra(self, select=None, where=None, params=None, tables=None,
- order_by=None, select_params=None):
- """
- Adds extra SQL fragments to the query.
- """
- assert self.query.can_filter(), \
- "Cannot change a query once a slice has been taken"
- clone = self._clone()
- clone.query.add_extra(select, select_params, where, params, tables, order_by)
- return clone
-
- def reverse(self):
- """
- Reverses the ordering of the QuerySet.
- """
- clone = self._clone()
- clone.query.standard_ordering = not clone.query.standard_ordering
- return clone
-
- def defer(self, *fields):
- """
- Defers the loading of data for certain fields until they are accessed.
- The set of fields to defer is added to any existing set of deferred
- fields. The only exception to this is if None is passed in as the only
- parameter, in which case all deferrals are removed (None acts as a
- reset option).
- """
- clone = self._clone()
- if fields == (None,):
- clone.query.clear_deferred_loading()
- else:
- clone.query.add_deferred_loading(fields)
- return clone
-
- def only(self, *fields):
- """
- Essentially, the opposite of defer. Only the fields passed into this
- method and that are not already specified as deferred are loaded
- immediately when the queryset is evaluated.
- """
- if fields == (None,):
- # Can only pass None to defer(), not only(), as the rest option.
- # That won't stop people trying to do this, so let's be explicit.
- raise TypeError("Cannot pass None as an argument to only().")
- clone = self._clone()
- clone.query.add_immediate_loading(fields)
- return clone
-
- def using(self, alias):
- """
- Selects which database this QuerySet should excecute its query against.
- """
- clone = self._clone()
- clone._db = alias
- return clone
-
- ###################################
- # PUBLIC INTROSPECTION ATTRIBUTES #
- ###################################
-
- def ordered(self):
- """
- Returns True if the QuerySet is ordered -- i.e. has an order_by()
- clause or a default ordering on the model.
- """
- if self.query.extra_order_by or self.query.order_by:
- return True
- elif self.query.default_ordering and self.query.get_meta().ordering:
- return True
- else:
- return False
- ordered = property(ordered)
-
- @property
- def db(self):
- "Return the database that will be used if this query is executed now"
- if self._for_write:
- return self._db or router.db_for_write(self.model)
- return self._db or router.db_for_read(self.model)
-
- ###################
- # PRIVATE METHODS #
- ###################
- def _batched_insert(self, objs, fields, batch_size):
- """
- A little helper method for bulk_insert to insert the bulk one batch
- at a time. Inserts recursively a batch from the front of the bulk and
- then _batched_insert() the remaining objects again.
- """
- if not objs:
- return
- ops = connections[self.db].ops
- batch_size = (batch_size or max(ops.bulk_batch_size(fields, objs), 1))
- for batch in [objs[i:i+batch_size]
- for i in range(0, len(objs), batch_size)]:
- self.model._base_manager._insert(batch, fields=fields,
- using=self.db)
-
- def _clone(self, klass=None, setup=False, **kwargs):
- if klass is None:
- klass = self.__class__
- query = self.query.clone()
- if self._sticky_filter:
- query.filter_is_sticky = True
- c = klass(model=self.model, query=query, using=self._db)
- c._for_write = self._for_write
- c._prefetch_related_lookups = self._prefetch_related_lookups[:]
- c._known_related_objects = self._known_related_objects
- c.__dict__.update(kwargs)
- if setup and hasattr(c, '_setup_query'):
- c._setup_query()
- return c
-
- def _fetch_all(self):
- if self._result_cache is None:
- self._result_cache = list(self.iterator())
- if self._prefetch_related_lookups and not self._prefetch_done:
- self._prefetch_related_objects()
-
- def _next_is_sticky(self):
- """
- Indicates that the next filter call and the one following that should
- be treated as a single filter. This is only important when it comes to
- determining when to reuse tables for many-to-many filters. Required so
- that we can filter naturally on the results of related managers.
-
- This doesn't return a clone of the current QuerySet (it returns
- "self"). The method is only used internally and should be immediately
- followed by a filter() that does create a clone.
- """
- self._sticky_filter = True
- return self
-
- def _merge_sanity_check(self, other):
- """
- Checks that we are merging two comparable QuerySet classes. By default
- this does nothing, but see the ValuesQuerySet for an example of where
- it's useful.
- """
- pass
-
- def _merge_known_related_objects(self, other):
- """
- Keep track of all known related objects from either QuerySet instance.
- """
- for field, objects in other._known_related_objects.items():
- self._known_related_objects.setdefault(field, {}).update(objects)
-
- def _setup_aggregate_query(self, aggregates):
- """
- Prepare the query for computing a result that contains aggregate annotations.
- """
- opts = self.model._meta
- if self.query.group_by is None:
- field_names = [f.attname for f in opts.concrete_fields]
- self.query.add_fields(field_names, False)
- self.query.set_group_by()
-
- def _prepare(self):
- return self
-
- def _as_sql(self, connection):
- """
- Returns the internal query's SQL and parameters (as a tuple).
- """
- obj = self.values("pk")
- if obj._db is None or connection == connections[obj._db]:
- return obj.query.get_compiler(connection=connection).as_nested_sql()
- raise ValueError("Can't do subqueries with queries on different DBs.")
-
- # When used as part of a nested query, a queryset will never be an "always
- # empty" result.
- value_annotation = True
-
-class InstanceCheckMeta(type):
- def __instancecheck__(self, instance):
- return instance.query.is_empty()
-
-class EmptyQuerySet(six.with_metaclass(InstanceCheckMeta)):
- """
- Marker class usable for checking if a queryset is empty by .none():
- isinstance(qs.none(), EmptyQuerySet) -> True
- """
-
- def __init__(self, *args, **kwargs):
- raise TypeError("EmptyQuerySet can't be instantiated")
-
-class ValuesQuerySet(QuerySet):
- def __init__(self, *args, **kwargs):
- super(ValuesQuerySet, self).__init__(*args, **kwargs)
- # select_related isn't supported in values(). (FIXME -#3358)
- self.query.select_related = False
-
- # QuerySet.clone() will also set up the _fields attribute with the
- # names of the model fields to select.
-
- def iterator(self):
- # Purge any extra columns that haven't been explicitly asked for
- extra_names = list(self.query.extra_select)
- field_names = self.field_names
- aggregate_names = list(self.query.aggregate_select)
-
- names = extra_names + field_names + aggregate_names
-
- for row in self.query.get_compiler(self.db).results_iter():
- yield dict(zip(names, row))
-
- def delete(self):
- # values().delete() doesn't work currently - make sure it raises an
- # user friendly error.
- raise TypeError("Queries with .values() or .values_list() applied "
- "can't be deleted")
-
- def _setup_query(self):
- """
- Constructs the field_names list that the values query will be
- retrieving.
-
- Called by the _clone() method after initializing the rest of the
- instance.
- """
- self.query.clear_deferred_loading()
- self.query.clear_select_fields()
-
- if self._fields:
- self.extra_names = []
- self.aggregate_names = []
- if not self.query.extra and not self.query.aggregates:
- # Short cut - if there are no extra or aggregates, then
- # the values() clause must be just field names.
- self.field_names = list(self._fields)
- else:
- self.query.default_cols = False
- self.field_names = []
- for f in self._fields:
- # we inspect the full extra_select list since we might
- # be adding back an extra select item that we hadn't
- # had selected previously.
- if f in self.query.extra:
- self.extra_names.append(f)
- elif f in self.query.aggregate_select:
- self.aggregate_names.append(f)
- else:
- self.field_names.append(f)
- else:
- # Default to all fields.
- self.extra_names = None
- self.field_names = [f.attname for f in self.model._meta.concrete_fields]
- self.aggregate_names = None
-
- self.query.select = []
- if self.extra_names is not None:
- self.query.set_extra_mask(self.extra_names)
- self.query.add_fields(self.field_names, True)
- if self.aggregate_names is not None:
- self.query.set_aggregate_mask(self.aggregate_names)
-
- def _clone(self, klass=None, setup=False, **kwargs):
- """
- Cloning a ValuesQuerySet preserves the current fields.
- """
- c = super(ValuesQuerySet, self)._clone(klass, **kwargs)
- if not hasattr(c, '_fields'):
- # Only clone self._fields if _fields wasn't passed into the cloning
- # call directly.
- c._fields = self._fields[:]
- c.field_names = self.field_names
- c.extra_names = self.extra_names
- c.aggregate_names = self.aggregate_names
- if setup and hasattr(c, '_setup_query'):
- c._setup_query()
- return c
-
- def _merge_sanity_check(self, other):
- super(ValuesQuerySet, self)._merge_sanity_check(other)
- if (set(self.extra_names) != set(other.extra_names) or
- set(self.field_names) != set(other.field_names) or
- self.aggregate_names != other.aggregate_names):
- raise TypeError("Merging '%s' classes must involve the same values in each case."
- % self.__class__.__name__)
-
- def _setup_aggregate_query(self, aggregates):
- """
- Prepare the query for computing a result that contains aggregate annotations.
- """
- self.query.set_group_by()
-
- if self.aggregate_names is not None:
- self.aggregate_names.extend(aggregates)
- self.query.set_aggregate_mask(self.aggregate_names)
-
- super(ValuesQuerySet, self)._setup_aggregate_query(aggregates)
-
- def _as_sql(self, connection):
- """
- For ValuesQuerySet (and subclasses like ValuesListQuerySet), they can
- only be used as nested queries if they're already set up to select only
- a single field (in which case, that is the field column that is
- returned). This differs from QuerySet.as_sql(), where the column to
- select is set up by Django.
- """
- if ((self._fields and len(self._fields) > 1) or
- (not self._fields and len(self.model._meta.fields) > 1)):
- raise TypeError('Cannot use a multi-field %s as a filter value.'
- % self.__class__.__name__)
-
- obj = self._clone()
- if obj._db is None or connection == connections[obj._db]:
- return obj.query.get_compiler(connection=connection).as_nested_sql()
- raise ValueError("Can't do subqueries with queries on different DBs.")
-
- def _prepare(self):
- """
- Validates that we aren't trying to do a query like
- value__in=qs.values('value1', 'value2'), which isn't valid.
- """
- if ((self._fields and len(self._fields) > 1) or
- (not self._fields and len(self.model._meta.fields) > 1)):
- raise TypeError('Cannot use a multi-field %s as a filter value.'
- % self.__class__.__name__)
- return self
-
-
-class ValuesListQuerySet(ValuesQuerySet):
- def iterator(self):
- if self.flat and len(self._fields) == 1:
- for row in self.query.get_compiler(self.db).results_iter():
- yield row[0]
- elif not self.query.extra_select and not self.query.aggregate_select:
- for row in self.query.get_compiler(self.db).results_iter():
- yield tuple(row)
- else:
- # When extra(select=...) or an annotation is involved, the extra
- # cols are always at the start of the row, and we need to reorder
- # the fields to match the order in self._fields.
- extra_names = list(self.query.extra_select)
- field_names = self.field_names
- aggregate_names = list(self.query.aggregate_select)
-
- names = extra_names + field_names + aggregate_names
-
- # If a field list has been specified, use it. Otherwise, use the
- # full list of fields, including extras and aggregates.
- if self._fields:
- fields = list(self._fields) + [f for f in aggregate_names if f not in self._fields]
- else:
- fields = names
-
- for row in self.query.get_compiler(self.db).results_iter():
- data = dict(zip(names, row))
- yield tuple([data[f] for f in fields])
-
- def _clone(self, *args, **kwargs):
- clone = super(ValuesListQuerySet, self)._clone(*args, **kwargs)
- if not hasattr(clone, "flat"):
- # Only assign flat if the clone didn't already get it from kwargs
- clone.flat = self.flat
- return clone
-
-
-class DateQuerySet(QuerySet):
- def iterator(self):
- return self.query.get_compiler(self.db).results_iter()
-
- def _setup_query(self):
- """
- Sets up any special features of the query attribute.
-
- Called by the _clone() method after initializing the rest of the
- instance.
- """
- self.query.clear_deferred_loading()
- self.query = self.query.clone(klass=sql.DateQuery, setup=True)
- self.query.select = []
- self.query.add_select(self._field_name, self._kind, self._order)
-
- def _clone(self, klass=None, setup=False, **kwargs):
- c = super(DateQuerySet, self)._clone(klass, False, **kwargs)
- c._field_name = self._field_name
- c._kind = self._kind
- if setup and hasattr(c, '_setup_query'):
- c._setup_query()
- return c
-
-
-class DateTimeQuerySet(QuerySet):
- def iterator(self):
- return self.query.get_compiler(self.db).results_iter()
-
- def _setup_query(self):
- """
- Sets up any special features of the query attribute.
-
- Called by the _clone() method after initializing the rest of the
- instance.
- """
- self.query.clear_deferred_loading()
- self.query = self.query.clone(klass=sql.DateTimeQuery, setup=True, tzinfo=self._tzinfo)
- self.query.select = []
- self.query.add_select(self._field_name, self._kind, self._order)
-
- def _clone(self, klass=None, setup=False, **kwargs):
- c = super(DateTimeQuerySet, self)._clone(klass, False, **kwargs)
- c._field_name = self._field_name
- c._kind = self._kind
- c._tzinfo = self._tzinfo
- if setup and hasattr(c, '_setup_query'):
- c._setup_query()
- return c
-
-
-def get_klass_info(klass, max_depth=0, cur_depth=0, requested=None,
- only_load=None, from_parent=None):
- """
- Helper function that recursively returns an information for a klass, to be
- used in get_cached_row. It exists just to compute this information only
- once for entire queryset. Otherwise it would be computed for each row, which
- leads to poor perfomance on large querysets.
-
- Arguments:
- * klass - the class to retrieve (and instantiate)
- * max_depth - the maximum depth to which a select_related()
- relationship should be explored.
- * cur_depth - the current depth in the select_related() tree.
- Used in recursive calls to determin if we should dig deeper.
- * requested - A dictionary describing the select_related() tree
- that is to be retrieved. keys are field names; values are
- dictionaries describing the keys on that related object that
- are themselves to be select_related().
- * only_load - if the query has had only() or defer() applied,
- this is the list of field names that will be returned. If None,
- the full field list for `klass` can be assumed.
- * from_parent - the parent model used to get to this model
-
- Note that when travelling from parent to child, we will only load child
- fields which aren't in the parent.
- """
- if max_depth and requested is None and cur_depth > max_depth:
- # We've recursed deeply enough; stop now.
- return None
-
- if only_load:
- load_fields = only_load.get(klass) or set()
- # When we create the object, we will also be creating populating
- # all the parent classes, so traverse the parent classes looking
- # for fields that must be included on load.
- for parent in klass._meta.get_parent_list():
- fields = only_load.get(parent)
- if fields:
- load_fields.update(fields)
- else:
- load_fields = None
-
- if load_fields:
- # Handle deferred fields.
- skip = set()
- init_list = []
- # Build the list of fields that *haven't* been requested
- for field, model in klass._meta.get_concrete_fields_with_model():
- if field.name not in load_fields:
- skip.add(field.attname)
- elif from_parent and issubclass(from_parent, model.__class__):
- # Avoid loading fields already loaded for parent model for
- # child models.
- continue
- else:
- init_list.append(field.attname)
- # Retrieve all the requested fields
- field_count = len(init_list)
- if skip:
- klass = deferred_class_factory(klass, skip)
- field_names = init_list
- else:
- field_names = ()
- else:
- # Load all fields on klass
-
- field_count = len(klass._meta.concrete_fields)
- # Check if we need to skip some parent fields.
- if from_parent and len(klass._meta.local_concrete_fields) != len(klass._meta.concrete_fields):
- # Only load those fields which haven't been already loaded into
- # 'from_parent'.
- non_seen_models = [p for p in klass._meta.get_parent_list()
- if not issubclass(from_parent, p)]
- # Load local fields, too...
- non_seen_models.append(klass)
- field_names = [f.attname for f in klass._meta.concrete_fields
- if f.model in non_seen_models]
- field_count = len(field_names)
- # Try to avoid populating field_names variable for perfomance reasons.
- # If field_names variable is set, we use **kwargs based model init
- # which is slower than normal init.
- if field_count == len(klass._meta.concrete_fields):
- field_names = ()
-
- restricted = requested is not None
-
- related_fields = []
- for f in klass._meta.fields:
- if select_related_descend(f, restricted, requested, load_fields):
- if restricted:
- next = requested[f.name]
- else:
- next = None
- klass_info = get_klass_info(f.rel.to, max_depth=max_depth, cur_depth=cur_depth+1,
- requested=next, only_load=only_load)
- related_fields.append((f, klass_info))
-
- reverse_related_fields = []
- if restricted:
- for o in klass._meta.get_all_related_objects():
- if o.field.unique and select_related_descend(o.field, restricted, requested,
- only_load.get(o.model), reverse=True):
- next = requested[o.field.related_query_name()]
- parent = klass if issubclass(o.model, klass) else None
- klass_info = get_klass_info(o.model, max_depth=max_depth, cur_depth=cur_depth+1,
- requested=next, only_load=only_load, from_parent=parent)
- reverse_related_fields.append((o.field, klass_info))
- if field_names:
- pk_idx = field_names.index(klass._meta.pk.attname)
- else:
- pk_idx = klass._meta.pk_index()
-
- return klass, field_names, field_count, related_fields, reverse_related_fields, pk_idx
-
-
-def get_cached_row(row, index_start, using, klass_info, offset=0,
- parent_data=()):
- """
- Helper function that recursively returns an object with the specified
- related attributes already populated.
-
- This method may be called recursively to populate deep select_related()
- clauses.
-
- Arguments:
- * row - the row of data returned by the database cursor
- * index_start - the index of the row at which data for this
- object is known to start
- * offset - the number of additional fields that are known to
- exist in row for `klass`. This usually means the number of
- annotated results on `klass`.
- * using - the database alias on which the query is being executed.
- * klass_info - result of the get_klass_info function
- * parent_data - parent model data in format (field, value). Used
- to populate the non-local fields of child models.
- """
- if klass_info is None:
- return None
- klass, field_names, field_count, related_fields, reverse_related_fields, pk_idx = klass_info
-
-
- fields = row[index_start : index_start + field_count]
- # If the pk column is None (or the Oracle equivalent ''), then the related
- # object must be non-existent - set the relation to None.
- if fields[pk_idx] == None or fields[pk_idx] == '':
- obj = None
- elif field_names:
- fields = list(fields)
- for rel_field, value in parent_data:
- field_names.append(rel_field.attname)
- fields.append(value)
- obj = klass(**dict(zip(field_names, fields)))
- else:
- obj = klass(*fields)
- # If an object was retrieved, set the database state.
- if obj:
- obj._state.db = using
- obj._state.adding = False
-
- # Instantiate related fields
- index_end = index_start + field_count + offset
- # Iterate over each related object, populating any
- # select_related() fields
- for f, klass_info in related_fields:
- # Recursively retrieve the data for the related object
- cached_row = get_cached_row(row, index_end, using, klass_info)
- # If the recursive descent found an object, populate the
- # descriptor caches relevant to the object
- if cached_row:
- rel_obj, index_end = cached_row
- if obj is not None:
- # If the base object exists, populate the
- # descriptor cache
- setattr(obj, f.get_cache_name(), rel_obj)
- if f.unique and rel_obj is not None:
- # If the field is unique, populate the
- # reverse descriptor cache on the related object
- setattr(rel_obj, f.related.get_cache_name(), obj)
-
- # Now do the same, but for reverse related objects.
- # Only handle the restricted case - i.e., don't do a depth
- # descent into reverse relations unless explicitly requested
- for f, klass_info in reverse_related_fields:
- # Transfer data from this object to childs.
- parent_data = []
- for rel_field, rel_model in klass_info[0]._meta.get_fields_with_model():
- if rel_model is not None and isinstance(obj, rel_model):
- parent_data.append((rel_field, getattr(obj, rel_field.attname)))
- # Recursively retrieve the data for the related object
- cached_row = get_cached_row(row, index_end, using, klass_info,
- parent_data=parent_data)
- # If the recursive descent found an object, populate the
- # descriptor caches relevant to the object
- if cached_row:
- rel_obj, index_end = cached_row
- if obj is not None:
- # populate the reverse descriptor cache
- setattr(obj, f.related.get_cache_name(), rel_obj)
- if rel_obj is not None:
- # If the related object exists, populate
- # the descriptor cache.
- setattr(rel_obj, f.get_cache_name(), obj)
- # Populate related object caches using parent data.
- for rel_field, _ in parent_data:
- if rel_field.rel:
- setattr(rel_obj, rel_field.attname, getattr(obj, rel_field.attname))
- try:
- cached_obj = getattr(obj, rel_field.get_cache_name())
- setattr(rel_obj, rel_field.get_cache_name(), cached_obj)
- except AttributeError:
- # Related object hasn't been cached yet
- pass
- return obj, index_end
-
-
-class RawQuerySet(object):
- """
- Provides an iterator which converts the results of raw SQL queries into
- annotated model instances.
- """
- def __init__(self, raw_query, model=None, query=None, params=None,
- translations=None, using=None):
- self.raw_query = raw_query
- self.model = model
- self._db = using
- self.query = query or sql.RawQuery(sql=raw_query, using=self.db, params=params)
- self.params = params or ()
- self.translations = translations or {}
-
- def __iter__(self):
- # Mapping of attrnames to row column positions. Used for constructing
- # the model using kwargs, needed when not all model's fields are present
- # in the query.
- model_init_field_names = {}
- # A list of tuples of (column name, column position). Used for
- # annotation fields.
- annotation_fields = []
-
- # Cache some things for performance reasons outside the loop.
- db = self.db
- compiler = connections[db].ops.compiler('SQLCompiler')(
- self.query, connections[db], db
- )
- need_resolv_columns = hasattr(compiler, 'resolve_columns')
-
- query = iter(self.query)
-
- # Find out which columns are model's fields, and which ones should be
- # annotated to the model.
- for pos, column in enumerate(self.columns):
- if column in self.model_fields:
- model_init_field_names[self.model_fields[column].attname] = pos
- else:
- annotation_fields.append((column, pos))
-
- # Find out which model's fields are not present in the query.
- skip = set()
- for field in self.model._meta.fields:
- if field.attname not in model_init_field_names:
- skip.add(field.attname)
- if skip:
- if self.model._meta.pk.attname in skip:
- raise InvalidQuery('Raw query must include the primary key')
- model_cls = deferred_class_factory(self.model, skip)
- else:
- model_cls = self.model
- # All model's fields are present in the query. So, it is possible
- # to use *args based model instantation. For each field of the model,
- # record the query column position matching that field.
- model_init_field_pos = []
- for field in self.model._meta.fields:
- model_init_field_pos.append(model_init_field_names[field.attname])
- if need_resolv_columns:
- fields = [self.model_fields.get(c, None) for c in self.columns]
- # Begin looping through the query values.
- for values in query:
- if need_resolv_columns:
- values = compiler.resolve_columns(values, fields)
- # Associate fields to values
- if skip:
- model_init_kwargs = {}
- for attname, pos in six.iteritems(model_init_field_names):
- model_init_kwargs[attname] = values[pos]
- instance = model_cls(**model_init_kwargs)
- else:
- model_init_args = [values[pos] for pos in model_init_field_pos]
- instance = model_cls(*model_init_args)
- if annotation_fields:
- for column, pos in annotation_fields:
- setattr(instance, column, values[pos])
-
- instance._state.db = db
- instance._state.adding = False
-
- yield instance
-
- def __repr__(self):
- text = self.raw_query
- if self.params:
- text = text % (self.params if hasattr(self.params, 'keys') else tuple(self.params))
- return "<RawQuerySet: %r>" % text
-
- def __getitem__(self, k):
- return list(self)[k]
-
- @property
- def db(self):
- "Return the database that will be used if this query is executed now"
- return self._db or router.db_for_read(self.model)
-
- def using(self, alias):
- """
- Selects which database this Raw QuerySet should excecute it's query against.
- """
- return RawQuerySet(self.raw_query, model=self.model,
- query=self.query.clone(using=alias),
- params=self.params, translations=self.translations,
- using=alias)
-
- @property
- def columns(self):
- """
- A list of model field names in the order they'll appear in the
- query results.
- """
- if not hasattr(self, '_columns'):
- self._columns = self.query.get_columns()
-
- # Adjust any column names which don't match field names
- for (query_name, model_name) in self.translations.items():
- try:
- index = self._columns.index(query_name)
- self._columns[index] = model_name
- except ValueError:
- # Ignore translations for non-existant column names
- pass
-
- return self._columns
-
- @property
- def model_fields(self):
- """
- A dict mapping column names to model field names.
- """
- if not hasattr(self, '_model_fields'):
- converter = connections[self.db].introspection.table_name_converter
- self._model_fields = {}
- for field in self.model._meta.fields:
- name, column = field.get_attname_column()
- self._model_fields[converter(column)] = field
- 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
-
- Populates prefetched objects caches for a list of results
- from a QuerySet
- """
- if len(result_cache) == 0:
- return # nothing to do
-
- model = result_cache[0].__class__
-
- # We need to be able to dynamically add to the list of prefetch_related
- # lookups that we look up (see below). So we need some book keeping to
- # ensure we don't do duplicate work.
- done_lookups = set() # list of lookups like foo__bar__baz
- done_queries = {} # dictionary of things like 'foo__bar': [results]
-
- auto_lookups = [] # we add to this as we go through.
- followed_descriptors = set() # recursion protection
-
- all_lookups = itertools.chain(related_lookups, auto_lookups)
- for lookup in all_lookups:
- if lookup in done_lookups:
- # We've done exactly this already, skip the whole thing
- continue
- done_lookups.add(lookup)
-
- # Top level, the list of objects to decorate is the result cache
- # from the primary QuerySet. It won't be for deeper levels.
- obj_list = result_cache
-
- attrs = lookup.split(LOOKUP_SEP)
- for level, attr in enumerate(attrs):
- # Prepare main instances
- if len(obj_list) == 0:
- break
-
- current_lookup = LOOKUP_SEP.join(attrs[0:level+1])
- if current_lookup in done_queries:
- # Skip any prefetching, and any object preparation
- obj_list = done_queries[current_lookup]
- continue
-
- # Prepare objects:
- good_objects = True
- for obj in obj_list:
- # Since prefetching can re-use instances, it is possible to have
- # the same instance multiple times in obj_list, so obj might
- # already be prepared.
- if not hasattr(obj, '_prefetched_objects_cache'):
- try:
- obj._prefetched_objects_cache = {}
- except AttributeError:
- # Must be in a QuerySet subclass that is not returning
- # Model instances, either in Django or 3rd
- # party. prefetch_related() doesn't make sense, so quit
- # now.
- good_objects = False
- break
- if not good_objects:
- break
-
- # Descend down tree
-
- # We assume that objects retrieved are homogenous (which is the premise
- # of prefetch_related), so what applies to first object applies to all.
- first_obj = obj_list[0]
- prefetcher, descriptor, attr_found, is_fetched = get_prefetcher(first_obj, attr)
-
- if not attr_found:
- raise AttributeError("Cannot find '%s' on %s object, '%s' is an invalid "
- "parameter to prefetch_related()" %
- (attr, first_obj.__class__.__name__, lookup))
-
- if level == len(attrs) - 1 and prefetcher is None:
- # Last one, this *must* resolve to something that supports
- # prefetching, otherwise there is no point adding it and the
- # developer asking for it has made a mistake.
- raise ValueError("'%s' does not resolve to a item that supports "
- "prefetching - this is an invalid parameter to "
- "prefetch_related()." % lookup)
-
- if prefetcher is not None and not is_fetched:
- obj_list, additional_prl = prefetch_one_level(obj_list, prefetcher, attr)
- # We need to ensure we don't keep adding lookups from the
- # same relationships to stop infinite recursion. So, if we
- # are already on an automatically added lookup, don't add
- # the new lookups from relationships we've seen already.
- if not (lookup in auto_lookups and
- descriptor in followed_descriptors):
- for f in additional_prl:
- new_prl = LOOKUP_SEP.join([current_lookup, f])
- auto_lookups.append(new_prl)
- done_queries[current_lookup] = obj_list
- followed_descriptors.add(descriptor)
- else:
- # Either a singly related object that has already been fetched
- # (e.g. via select_related), or hopefully some other property
- # that doesn't support prefetching but needs to be traversed.
-
- # We replace the current list of parent objects with the list
- # of related objects, filtering out empty or missing values so
- # that we can continue with nullable or reverse relations.
- new_obj_list = []
- for obj in obj_list:
- try:
- new_obj = getattr(obj, attr)
- except exceptions.ObjectDoesNotExist:
- continue
- if new_obj is None:
- continue
- new_obj_list.append(new_obj)
- obj_list = new_obj_list
-
-
-def get_prefetcher(instance, attr):
- """
- For the attribute 'attr' on the given instance, finds
- an object that has a get_prefetch_queryset().
- Returns a 4 tuple containing:
- (the object with get_prefetch_queryset (or None),
- the descriptor object representing this relationship (or None),
- a boolean that is False if the attribute was not found at all,
- a boolean that is True if the attribute has already been fetched)
- """
- prefetcher = None
- attr_found = False
- is_fetched = False
-
- # For singly related objects, we have to avoid getting the attribute
- # from the object, as this will trigger the query. So we first try
- # on the class, in order to get the descriptor object.
- rel_obj_descriptor = getattr(instance.__class__, attr, None)
- if rel_obj_descriptor is None:
- try:
- rel_obj = getattr(instance, attr)
- attr_found = True
- except AttributeError:
- pass
- else:
- attr_found = True
- if rel_obj_descriptor:
- # singly related object, descriptor object has the
- # get_prefetch_queryset() method.
- if hasattr(rel_obj_descriptor, 'get_prefetch_queryset'):
- prefetcher = rel_obj_descriptor
- if rel_obj_descriptor.is_cached(instance):
- is_fetched = True
- else:
- # descriptor doesn't support prefetching, so we go ahead and get
- # the attribute on the instance rather than the class to
- # support many related managers
- rel_obj = getattr(instance, attr)
- if hasattr(rel_obj, 'get_prefetch_queryset'):
- prefetcher = rel_obj
- return prefetcher, rel_obj_descriptor, attr_found, is_fetched
-
-
-def prefetch_one_level(instances, prefetcher, attname):
- """
- Helper function for prefetch_related_objects
-
- Runs prefetches on all instances using the prefetcher object,
- assigning results to relevant caches in instance.
-
- The prefetched objects are returned, along with any additional
- prefetches that must be done due to prefetch_related lookups
- found from default managers.
- """
- # prefetcher must have a method get_prefetch_queryset() which takes a list
- # of instances, and returns a tuple:
-
- # (queryset of instances of self.model that are related to passed in instances,
- # callable that gets value to be matched for returned instances,
- # callable that gets value to be matched for passed in instances,
- # boolean that is True for singly related objects,
- # cache name to assign to).
-
- # The 'values to be matched' must be hashable as they will be used
- # in a dictionary.
-
- rel_qs, rel_obj_attr, instance_attr, single, cache_name =\
- prefetcher.get_prefetch_queryset(instances)
- # We have to handle the possibility that the default manager itself added
- # prefetch_related lookups to the QuerySet we just got back. We don't want to
- # trigger the prefetch_related functionality by evaluating the query.
- # Rather, we need to merge in the prefetch_related lookups.
- additional_prl = getattr(rel_qs, '_prefetch_related_lookups', [])
- if additional_prl:
- # Don't need to clone because the manager should have given us a fresh
- # instance, so we access an internal instead of using public interface
- # for performance reasons.
- rel_qs._prefetch_related_lookups = []
-
- all_related_objects = list(rel_qs)
-
- rel_obj_cache = {}
- for rel_obj in all_related_objects:
- rel_attr_val = rel_obj_attr(rel_obj)
- rel_obj_cache.setdefault(rel_attr_val, []).append(rel_obj)
-
- for obj in instances:
- instance_attr_val = instance_attr(obj)
- vals = rel_obj_cache.get(instance_attr_val, [])
- if single:
- # Need to assign to single cache on instance
- setattr(obj, cache_name, vals[0] if vals else None)
- else:
- # Multi, attribute represents a manager with an .all() method that
- # returns a QuerySet
- qs = getattr(obj, attname).all()
- qs._result_cache = vals
- # We don't want the individual qs doing prefetch_related now, since we
- # have merged this into the current work.
- qs._prefetch_done = True
- obj._prefetched_objects_cache[cache_name] = qs
- return all_related_objects, additional_prl
diff --git a/lib/python2.7/site-packages/django/db/models/query_utils.py b/lib/python2.7/site-packages/django/db/models/query_utils.py
deleted file mode 100644
index ee7a56a..0000000
--- a/lib/python2.7/site-packages/django/db/models/query_utils.py
+++ /dev/null
@@ -1,205 +0,0 @@
-"""
-Various data structures used in query construction.
-
-Factored out from django.db.models.query to avoid making the main module very
-large and/or so that they can be used by other modules without getting into
-circular import difficulties.
-"""
-from __future__ import unicode_literals
-
-from django.db.backends import util
-from django.utils import six
-from django.utils import tree
-
-
-class InvalidQuery(Exception):
- """
- The query passed to raw isn't a safe query to use with raw.
- """
- pass
-
-
-class QueryWrapper(object):
- """
- A type that indicates the contents are an SQL fragment and the associate
- parameters. Can be used to pass opaque data to a where-clause, for example.
- """
- def __init__(self, sql, params):
- self.data = sql, list(params)
-
- def as_sql(self, qn=None, connection=None):
- return self.data
-
-class Q(tree.Node):
- """
- Encapsulates filters as objects that can then be combined logically (using
- & and |).
- """
- # Connection types
- AND = 'AND'
- OR = 'OR'
- default = AND
-
- def __init__(self, *args, **kwargs):
- super(Q, self).__init__(children=list(args) + list(six.iteritems(kwargs)))
-
- def _combine(self, other, conn):
- if not isinstance(other, Q):
- raise TypeError(other)
- obj = type(self)()
- obj.connector = conn
- obj.add(self, conn)
- obj.add(other, conn)
- return obj
-
- def __or__(self, other):
- return self._combine(other, self.OR)
-
- def __and__(self, other):
- return self._combine(other, self.AND)
-
- def __invert__(self):
- obj = type(self)()
- obj.add(self, self.AND)
- obj.negate()
- return obj
-
- def clone(self):
- clone = self.__class__._new_instance(
- children=[], connector=self.connector, negated=self.negated)
- for child in self.children:
- if hasattr(child, 'clone'):
- clone.children.append(child.clone())
- else:
- clone.children.append(child)
- return clone
-
-class DeferredAttribute(object):
- """
- A wrapper for a deferred-loading field. When the value is read from this
- object the first time, the query is executed.
- """
- def __init__(self, field_name, model):
- self.field_name = field_name
-
- def __get__(self, instance, owner):
- """
- Retrieves and caches the value from the datastore on the first lookup.
- Returns the cached value.
- """
- from django.db.models.fields import FieldDoesNotExist
- non_deferred_model = instance._meta.proxy_for_model
- opts = non_deferred_model._meta
-
- assert instance is not None
- data = instance.__dict__
- if data.get(self.field_name, self) is self:
- # self.field_name is the attname of the field, but only() takes the
- # actual name, so we need to translate it here.
- try:
- f = opts.get_field_by_name(self.field_name)[0]
- except FieldDoesNotExist:
- f = [f for f in opts.fields
- if f.attname == self.field_name][0]
- name = f.name
- # Let's see if the field is part of the parent chain. If so we
- # might be able to reuse the already loaded value. Refs #18343.
- val = self._check_parent_chain(instance, name)
- if val is None:
- # We use only() instead of values() here because we want the
- # various data coersion methods (to_python(), etc.) to be
- # called here.
- val = getattr(
- non_deferred_model._base_manager.only(name).using(
- instance._state.db).get(pk=instance.pk),
- self.field_name
- )
- data[self.field_name] = val
- return data[self.field_name]
-
- def __set__(self, instance, value):
- """
- Deferred loading attributes can be set normally (which means there will
- never be a database lookup involved.
- """
- instance.__dict__[self.field_name] = value
-
- def _check_parent_chain(self, instance, name):
- """
- Check if the field value can be fetched from a parent field already
- loaded in the instance. This can be done if the to-be fetched
- field is a primary key field.
- """
- opts = instance._meta
- f = opts.get_field_by_name(name)[0]
- link_field = opts.get_ancestor_link(f.model)
- if f.primary_key and f != link_field:
- return getattr(instance, link_field.attname)
- return None
-
-
-def select_related_descend(field, restricted, requested, load_fields, reverse=False):
- """
- Returns True if this field should be used to descend deeper for
- select_related() purposes. Used by both the query construction code
- (sql.query.fill_related_selections()) and the model instance creation code
- (query.get_klass_info()).
-
- Arguments:
- * field - the field to be checked
- * restricted - a boolean field, indicating if the field list has been
- manually restricted using a requested clause)
- * requested - The select_related() dictionary.
- * load_fields - the set of fields to be loaded on this model
- * reverse - boolean, True if we are checking a reverse select related
- """
- if not field.rel:
- return False
- if field.rel.parent_link and not reverse:
- return False
- if restricted:
- if reverse and field.related_query_name() not in requested:
- return False
- if not reverse and field.name not in requested:
- return False
- if not restricted and field.null:
- return False
- if load_fields:
- if field.name 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))
- return False
- return True
-
-# This function is needed because data descriptors must be defined on a class
-# object, not an instance, to have any effect.
-
-def deferred_class_factory(model, attrs):
- """
- Returns a class object that is a copy of "model" with the specified "attrs"
- being replaced with DeferredAttribute objects. The "pk_value" ties the
- deferred attributes to a particular instance of the model.
- """
- class Meta:
- proxy = True
- app_label = model._meta.app_label
-
- # The app_cache wants a unique name for each model, otherwise the new class
- # won't be created (we get an old one back). Therefore, we generate the
- # name using the passed in attrs. It's OK to reuse an existing class
- # object if the attrs are identical.
- name = "%s_Deferred_%s" % (model.__name__, '_'.join(sorted(list(attrs))))
- name = util.truncate_name(name, 80, 32)
-
- overrides = dict((attr, DeferredAttribute(attr, model)) for attr in attrs)
- overrides["Meta"] = Meta
- overrides["__module__"] = model.__module__
- overrides["_deferred"] = True
- return type(str(name), (model,), overrides)
-
-# The above function is also used to unpickle model instances with deferred
-# fields.
-deferred_class_factory.__safe_for_unpickling__ = True
diff --git a/lib/python2.7/site-packages/django/db/models/related.py b/lib/python2.7/site-packages/django/db/models/related.py
deleted file mode 100644
index 4b00dd3..0000000
--- a/lib/python2.7/site-packages/django/db/models/related.py
+++ /dev/null
@@ -1,67 +0,0 @@
-from collections import namedtuple
-
-from django.utils.encoding import smart_text
-from django.db.models.fields import BLANK_CHOICE_DASH
-
-# 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.
-PathInfo = namedtuple('PathInfo',
- 'from_opts to_opts target_fields join_field '
- 'm2m direct')
-
-class RelatedObject(object):
- def __init__(self, parent_model, model, field):
- self.parent_model = parent_model
- self.model = model
- self.opts = model._meta
- self.field = field
- self.name = '%s:%s' % (self.opts.app_label, self.opts.model_name)
- self.var_name = self.opts.model_name
-
- def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH,
- limit_to_currently_related=False):
- """Returns choices with a default blank choices included, for use
- as SelectField choices for this field.
-
- Analogue of django.db.models.fields.Field.get_choices, provided
- initially for utilisation by RelatedFieldListFilter.
- """
- first_choice = blank_choice if include_blank else []
- queryset = self.model._default_manager.all()
- if limit_to_currently_related:
- queryset = queryset.complex_filter(
- {'%s__isnull' % self.parent_model._meta.model_name: False})
- lst = [(x._get_pk_val(), smart_text(x)) for x in queryset]
- return first_choice + lst
-
- def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
- # Defer to the actual field definition for db prep
- return self.field.get_db_prep_lookup(lookup_type, value,
- connection=connection, prepared=prepared)
-
- def editable_fields(self):
- "Get the fields in this class that should be edited inline."
- return [f for f in self.opts.fields + self.opts.many_to_many if f.editable and f != self.field]
-
- def __repr__(self):
- return "<RelatedObject: %s related to %s>" % (self.name, self.field.name)
-
- def get_accessor_name(self):
- # This method encapsulates the logic that decides what name to give an
- # accessor descriptor that retrieves related many-to-one or
- # many-to-many objects. It uses the lower-cased object_name + "_set",
- # but this can be overridden with the "related_name" option.
- if self.field.rel.multiple:
- # If this is a symmetrical m2m relation on self, there is no reverse accessor.
- if getattr(self.field.rel, 'symmetrical', False) and self.model == self.parent_model:
- return None
- return self.field.rel.related_name or (self.opts.model_name + '_set')
- else:
- return self.field.rel.related_name or (self.opts.model_name)
-
- def get_cache_name(self):
- return "_%s_cache" % self.get_accessor_name()
-
- def get_path_info(self):
- return self.field.get_reverse_path_info()
diff --git a/lib/python2.7/site-packages/django/db/models/signals.py b/lib/python2.7/site-packages/django/db/models/signals.py
deleted file mode 100644
index 0782442..0000000
--- a/lib/python2.7/site-packages/django/db/models/signals.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from django.dispatch import Signal
-
-class_prepared = Signal(providing_args=["class"])
-
-pre_init = Signal(providing_args=["instance", "args", "kwargs"], use_caching=True)
-post_init = Signal(providing_args=["instance"], use_caching=True)
-
-pre_save = Signal(providing_args=["instance", "raw", "using", "update_fields"],
- use_caching=True)
-post_save = Signal(providing_args=["instance", "raw", "created", "using", "update_fields"], use_caching=True)
-
-pre_delete = Signal(providing_args=["instance", "using"], use_caching=True)
-post_delete = Signal(providing_args=["instance", "using"], use_caching=True)
-
-pre_syncdb = Signal(providing_args=["app", "create_models", "verbosity", "interactive", "db"])
-post_syncdb = Signal(providing_args=["class", "app", "created_models", "verbosity", "interactive", "db"])
-
-m2m_changed = Signal(providing_args=["action", "instance", "reverse", "model", "pk_set", "using"], use_caching=True)
diff --git a/lib/python2.7/site-packages/django/db/models/sql/__init__.py b/lib/python2.7/site-packages/django/db/models/sql/__init__.py
deleted file mode 100644
index df5b74e..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from __future__ import absolute_import
-
-from django.db.models.sql.datastructures import EmptyResultSet
-from django.db.models.sql.subqueries import *
-from django.db.models.sql.query import *
-from django.db.models.sql.where import AND, OR
-
-
-__all__ = ['Query', 'AND', 'OR', 'EmptyResultSet']
diff --git a/lib/python2.7/site-packages/django/db/models/sql/aggregates.py b/lib/python2.7/site-packages/django/db/models/sql/aggregates.py
deleted file mode 100644
index 2bd2b2f..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/aggregates.py
+++ /dev/null
@@ -1,125 +0,0 @@
-"""
-Classes to represent the default SQL aggregate functions
-"""
-import copy
-
-from django.db.models.fields import IntegerField, FloatField
-
-# Fake fields used to identify aggregate types in data-conversion operations.
-ordinal_aggregate_field = IntegerField()
-computed_aggregate_field = FloatField()
-
-class Aggregate(object):
- """
- Default SQL Aggregate.
- """
- is_ordinal = False
- is_computed = False
- sql_template = '%(function)s(%(field)s)'
-
- def __init__(self, col, source=None, is_summary=False, **extra):
- """Instantiate an SQL aggregate
-
- * col is a column reference describing the subject field
- of the aggregate. It can be an alias, or a tuple describing
- a table and column name.
- * source is the underlying field or aggregate definition for
- the column reference. If the aggregate is not an ordinal or
- computed type, this reference is used to determine the coerced
- output type of the aggregate.
- * extra is a dictionary of additional data to provide for the
- aggregate definition
-
- Also utilizes the class variables:
- * sql_function, the name of the SQL function that implements the
- aggregate.
- * sql_template, a template string that is used to render the
- aggregate into SQL.
- * is_ordinal, a boolean indicating if the output of this aggregate
- is an integer (e.g., a count)
- * is_computed, a boolean indicating if this output of this aggregate
- is a computed float (e.g., an average), regardless of the input
- type.
-
- """
- self.col = col
- self.source = source
- self.is_summary = is_summary
- self.extra = extra
-
- # Follow the chain of aggregate sources back until you find an
- # actual field, or an aggregate that forces a particular output
- # type. This type of this field will be used to coerce values
- # retrieved from the database.
- tmp = self
-
- while tmp and isinstance(tmp, Aggregate):
- if getattr(tmp, 'is_ordinal', False):
- tmp = ordinal_aggregate_field
- elif getattr(tmp, 'is_computed', False):
- tmp = computed_aggregate_field
- else:
- tmp = tmp.source
-
- self.field = tmp
-
- def relabeled_clone(self, change_map):
- clone = copy.copy(self)
- if isinstance(self.col, (list, tuple)):
- clone.col = (change_map.get(self.col[0], self.col[0]), self.col[1])
- return clone
-
- def as_sql(self, qn, connection):
- "Return the aggregate, rendered as SQL with parameters."
- params = []
-
- if hasattr(self.col, 'as_sql'):
- field_name, params = self.col.as_sql(qn, connection)
- elif isinstance(self.col, (list, tuple)):
- field_name = '.'.join([qn(c) for c in self.col])
- else:
- field_name = self.col
-
- substitutions = {
- 'function': self.sql_function,
- 'field': field_name
- }
- substitutions.update(self.extra)
-
- return self.sql_template % substitutions, params
-
-
-class Avg(Aggregate):
- is_computed = True
- sql_function = 'AVG'
-
-class Count(Aggregate):
- is_ordinal = True
- sql_function = 'COUNT'
- sql_template = '%(function)s(%(distinct)s%(field)s)'
-
- def __init__(self, col, distinct=False, **extra):
- super(Count, self).__init__(col, distinct='DISTINCT ' if distinct else '', **extra)
-
-class Max(Aggregate):
- sql_function = 'MAX'
-
-class Min(Aggregate):
- sql_function = 'MIN'
-
-class StdDev(Aggregate):
- is_computed = True
-
- def __init__(self, col, sample=False, **extra):
- super(StdDev, self).__init__(col, **extra)
- self.sql_function = 'STDDEV_SAMP' if sample else 'STDDEV_POP'
-
-class Sum(Aggregate):
- sql_function = 'SUM'
-
-class Variance(Aggregate):
- is_computed = True
-
- def __init__(self, col, sample=False, **extra):
- super(Variance, self).__init__(col, **extra)
- self.sql_function = 'VAR_SAMP' if sample else 'VAR_POP'
diff --git a/lib/python2.7/site-packages/django/db/models/sql/compiler.py b/lib/python2.7/site-packages/django/db/models/sql/compiler.py
deleted file mode 100644
index ea7f9f4..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/compiler.py
+++ /dev/null
@@ -1,1128 +0,0 @@
-import datetime
-
-from django.conf import settings
-from django.core.exceptions import FieldError
-from django.db.backends.util import truncate_name
-from django.db.models.constants import LOOKUP_SEP
-from django.db.models.query_utils import select_related_descend, QueryWrapper
-from django.db.models.sql.constants import (SINGLE, MULTI, ORDER_DIR,
- GET_ITERATOR_CHUNK_SIZE, SelectInfo)
-from django.db.models.sql.datastructures import EmptyResultSet
-from django.db.models.sql.expressions import SQLEvaluator
-from django.db.models.sql.query import get_order_dir, Query
-from django.db.transaction import TransactionManagementError
-from django.db.utils import DatabaseError
-from django.utils import six
-from django.utils.six.moves import zip
-from django.utils import timezone
-
-
-class SQLCompiler(object):
- def __init__(self, query, connection, using):
- self.query = query
- self.connection = connection
- self.using = using
- self.quote_cache = {}
- # When ordering a queryset with distinct on a column not part of the
- # select set, the ordering column needs to be added to the select
- # clause. This information is needed both in SQL construction and
- # masking away the ordering selects from the returned row.
- self.ordering_aliases = []
- self.ordering_params = []
-
- def pre_sql_setup(self):
- """
- Does any necessary class setup immediately prior to producing SQL. This
- is for things that can't necessarily be done in __init__ because we
- might not have all the pieces in place at that time.
- # TODO: after the query has been executed, the altered state should be
- # cleaned. We are not using a clone() of the query here.
- """
- if not self.query.tables:
- self.query.join((None, self.query.get_meta().db_table, None))
- if (not self.query.select and self.query.default_cols and not
- self.query.included_inherited_models):
- self.query.setup_inherited_models()
- if self.query.select_related and not self.query.related_select_cols:
- self.fill_related_selections()
-
- def quote_name_unless_alias(self, name):
- """
- A wrapper around connection.ops.quote_name that doesn't quote aliases
- for table names. This avoids problems with some SQL dialects that treat
- quoted strings specially (e.g. PostgreSQL).
- """
- if name in self.quote_cache:
- return self.quote_cache[name]
- if ((name in self.query.alias_map and name not in self.query.table_map) or
- name in self.query.extra_select):
- self.quote_cache[name] = name
- return name
- r = self.connection.ops.quote_name(name)
- self.quote_cache[name] = r
- return r
-
- def as_sql(self, with_limits=True, with_col_aliases=False):
- """
- Creates the SQL for this query. Returns the SQL string and list of
- parameters.
-
- If 'with_limits' is False, any limit/offset information is not included
- in the query.
- """
- if with_limits and self.query.low_mark == self.query.high_mark:
- return '', ()
-
- self.pre_sql_setup()
- # After executing the query, we must get rid of any joins the query
- # setup created. So, take note of alias counts before the query ran.
- # However we do not want to get rid of stuff done in pre_sql_setup(),
- # as the pre_sql_setup will modify query state in a way that forbids
- # another run of it.
- self.refcounts_before = self.query.alias_refcount.copy()
- out_cols, s_params = self.get_columns(with_col_aliases)
- ordering, o_params, ordering_group_by = self.get_ordering()
-
- distinct_fields = self.get_distinct()
-
- # This must come after 'select', 'ordering' and 'distinct' -- see
- # docstring of get_from_clause() for details.
- from_, f_params = self.get_from_clause()
-
- qn = self.quote_name_unless_alias
-
- where, w_params = self.query.where.as_sql(qn=qn, connection=self.connection)
- having, h_params = self.query.having.as_sql(qn=qn, connection=self.connection)
- having_group_by = self.query.having.get_cols()
- params = []
- for val in six.itervalues(self.query.extra_select):
- params.extend(val[1])
-
- result = ['SELECT']
-
- if self.query.distinct:
- result.append(self.connection.ops.distinct_sql(distinct_fields))
- params.extend(o_params)
- result.append(', '.join(out_cols + self.ordering_aliases))
- params.extend(s_params)
- params.extend(self.ordering_params)
-
- result.append('FROM')
- result.extend(from_)
- params.extend(f_params)
-
- if where:
- result.append('WHERE %s' % where)
- params.extend(w_params)
-
- grouping, gb_params = self.get_grouping(having_group_by, ordering_group_by)
- if grouping:
- if distinct_fields:
- raise NotImplementedError(
- "annotate() + distinct(fields) not implemented.")
- if not ordering:
- ordering = self.connection.ops.force_no_ordering()
- result.append('GROUP BY %s' % ', '.join(grouping))
- params.extend(gb_params)
-
- if having:
- result.append('HAVING %s' % having)
- params.extend(h_params)
-
- if ordering:
- result.append('ORDER BY %s' % ', '.join(ordering))
-
- if with_limits:
- if self.query.high_mark is not None:
- result.append('LIMIT %d' % (self.query.high_mark - self.query.low_mark))
- if self.query.low_mark:
- if self.query.high_mark is None:
- val = self.connection.ops.no_limit_value()
- if val:
- result.append('LIMIT %d' % val)
- result.append('OFFSET %d' % self.query.low_mark)
-
- if self.query.select_for_update and self.connection.features.has_select_for_update:
- if self.connection.get_autocommit():
- raise TransactionManagementError("select_for_update cannot be used outside of a transaction.")
-
- # If we've been asked for a NOWAIT query but the backend does not support it,
- # raise a DatabaseError otherwise we could get an unexpected deadlock.
- nowait = self.query.select_for_update_nowait
- if nowait and not self.connection.features.has_select_for_update_nowait:
- raise DatabaseError('NOWAIT is not supported on this database backend.')
- result.append(self.connection.ops.for_update_sql(nowait=nowait))
-
- # Finally do cleanup - get rid of the joins we created above.
- self.query.reset_refcounts(self.refcounts_before)
-
- return ' '.join(result), tuple(params)
-
- def as_nested_sql(self):
- """
- Perform the same functionality as the as_sql() method, returning an
- SQL string and parameters. However, the alias prefixes are bumped
- beforehand (in a copy -- the current query isn't changed), and any
- ordering is removed if the query is unsliced.
-
- Used when nesting this query inside another.
- """
- obj = self.query.clone()
- if obj.low_mark == 0 and obj.high_mark is None:
- # If there is no slicing in use, then we can safely drop all ordering
- obj.clear_ordering(True)
- obj.bump_prefix()
- return obj.get_compiler(connection=self.connection).as_sql()
-
- def get_columns(self, with_aliases=False):
- """
- Returns the list of columns to use in the select statement, as well as
- a list any extra parameters that need to be included. If no columns
- have been specified, returns all columns relating to fields in the
- model.
-
- If 'with_aliases' is true, any column names that are duplicated
- (without the table names) are given unique aliases. This is needed in
- some cases to avoid ambiguity with nested queries.
- """
- qn = self.quote_name_unless_alias
- qn2 = self.connection.ops.quote_name
- result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in six.iteritems(self.query.extra_select)]
- params = []
- aliases = set(self.query.extra_select.keys())
- if with_aliases:
- col_aliases = aliases.copy()
- else:
- col_aliases = set()
- if self.query.select:
- only_load = self.deferred_to_columns()
- for col, _ in self.query.select:
- if isinstance(col, (list, tuple)):
- alias, column = col
- table = self.query.alias_map[alias].table_name
- if table in only_load and column not in only_load[table]:
- continue
- r = '%s.%s' % (qn(alias), qn(column))
- if with_aliases:
- if col[1] in col_aliases:
- c_alias = 'Col%d' % len(col_aliases)
- result.append('%s AS %s' % (r, c_alias))
- aliases.add(c_alias)
- col_aliases.add(c_alias)
- else:
- result.append('%s AS %s' % (r, qn2(col[1])))
- aliases.add(r)
- col_aliases.add(col[1])
- else:
- result.append(r)
- aliases.add(r)
- col_aliases.add(col[1])
- else:
- col_sql, col_params = col.as_sql(qn, self.connection)
- result.append(col_sql)
- params.extend(col_params)
-
- if hasattr(col, 'alias'):
- aliases.add(col.alias)
- col_aliases.add(col.alias)
-
- elif self.query.default_cols:
- cols, new_aliases = self.get_default_columns(with_aliases,
- col_aliases)
- result.extend(cols)
- aliases.update(new_aliases)
-
- max_name_length = self.connection.ops.max_name_length()
- for alias, aggregate in self.query.aggregate_select.items():
- agg_sql, agg_params = aggregate.as_sql(qn, self.connection)
- if alias is None:
- result.append(agg_sql)
- else:
- result.append('%s AS %s' % (agg_sql, qn(truncate_name(alias, max_name_length))))
- params.extend(agg_params)
-
- for (table, col), _ in self.query.related_select_cols:
- r = '%s.%s' % (qn(table), qn(col))
- if with_aliases and col in col_aliases:
- c_alias = 'Col%d' % len(col_aliases)
- result.append('%s AS %s' % (r, c_alias))
- aliases.add(c_alias)
- col_aliases.add(c_alias)
- else:
- result.append(r)
- aliases.add(r)
- col_aliases.add(col)
-
- self._select_aliases = aliases
- return result, params
-
- def get_default_columns(self, with_aliases=False, col_aliases=None,
- start_alias=None, opts=None, as_pairs=False, from_parent=None):
- """
- Computes the default columns for selecting every field in the base
- model. Will sometimes be called to pull in related models (e.g. via
- select_related), in which case "opts" and "start_alias" will be given
- to provide a starting point for the traversal.
-
- Returns a list of strings, quoted appropriately for use in SQL
- directly, as well as a set of aliases used in the select statement (if
- 'as_pairs' is True, returns a list of (alias, col_name) pairs instead
- of strings as the first component and None as the second component).
- """
- result = []
- if opts is None:
- opts = self.query.get_meta()
- qn = self.quote_name_unless_alias
- qn2 = self.connection.ops.quote_name
- aliases = set()
- only_load = self.deferred_to_columns()
- if not start_alias:
- start_alias = self.query.get_initial_alias()
- # The 'seen_models' is used to optimize checking the needed parent
- # alias for a given field. This also includes None -> start_alias to
- # be used by local fields.
- seen_models = {None: start_alias}
-
- for field, model in opts.get_concrete_fields_with_model():
- if from_parent and model is not None and issubclass(from_parent, model):
- # Avoid loading data for already loaded parents.
- continue
- alias = self.query.join_parent_model(opts, model, start_alias,
- seen_models)
- table = self.query.alias_map[alias].table_name
- if table in only_load and field.column not in only_load[table]:
- continue
- if as_pairs:
- result.append((alias, field))
- aliases.add(alias)
- continue
- if with_aliases and field.column in col_aliases:
- c_alias = 'Col%d' % len(col_aliases)
- result.append('%s.%s AS %s' % (qn(alias),
- qn2(field.column), c_alias))
- col_aliases.add(c_alias)
- aliases.add(c_alias)
- else:
- r = '%s.%s' % (qn(alias), qn2(field.column))
- result.append(r)
- aliases.add(r)
- if with_aliases:
- col_aliases.add(field.column)
- return result, aliases
-
- def get_distinct(self):
- """
- Returns a quoted list of fields to use in DISTINCT ON part of the query.
-
- Note that this method can alter the tables in the query, and thus it
- must be called before get_from_clause().
- """
- qn = self.quote_name_unless_alias
- qn2 = self.connection.ops.quote_name
- result = []
- opts = self.query.get_meta()
-
- for name in self.query.distinct_fields:
- parts = name.split(LOOKUP_SEP)
- field, cols, alias, _, _ = self._setup_joins(parts, opts, None)
- cols, alias = self._final_join_removal(cols, alias)
- for col in cols:
- result.append("%s.%s" % (qn(alias), qn2(col)))
- return result
-
- def get_ordering(self):
- """
- Returns a tuple containing a list representing the SQL elements in the
- "order by" clause, and the list of SQL elements that need to be added
- to the GROUP BY clause as a result of the ordering.
-
- Also sets the ordering_aliases attribute on this instance to a list of
- extra aliases needed in the select.
-
- Determining the ordering SQL can change the tables we need to include,
- so this should be run *before* get_from_clause().
- """
- if self.query.extra_order_by:
- ordering = self.query.extra_order_by
- elif not self.query.default_ordering:
- ordering = self.query.order_by
- else:
- ordering = (self.query.order_by
- or self.query.get_meta().ordering
- or [])
- qn = self.quote_name_unless_alias
- qn2 = self.connection.ops.quote_name
- distinct = self.query.distinct
- select_aliases = self._select_aliases
- result = []
- group_by = []
- ordering_aliases = []
- if self.query.standard_ordering:
- asc, desc = ORDER_DIR['ASC']
- else:
- asc, desc = ORDER_DIR['DESC']
-
- # It's possible, due to model inheritance, that normal usage might try
- # to include the same field more than once in the ordering. We track
- # the table/column pairs we use and discard any after the first use.
- processed_pairs = set()
-
- params = []
- ordering_params = []
- for pos, field in enumerate(ordering):
- if field == '?':
- result.append(self.connection.ops.random_function_sql())
- continue
- if isinstance(field, int):
- if field < 0:
- order = desc
- field = -field
- else:
- order = asc
- result.append('%s %s' % (field, order))
- group_by.append((str(field), []))
- continue
- col, order = get_order_dir(field, asc)
- if col in self.query.aggregate_select:
- result.append('%s %s' % (qn(col), order))
- continue
- if '.' in field:
- # This came in through an extra(order_by=...) addition. Pass it
- # on verbatim.
- table, col = col.split('.', 1)
- if (table, col) not in processed_pairs:
- elt = '%s.%s' % (qn(table), col)
- processed_pairs.add((table, col))
- if not distinct or elt in select_aliases:
- result.append('%s %s' % (elt, order))
- group_by.append((elt, []))
- elif get_order_dir(field)[0] not in self.query.extra:
- # 'col' is of the form 'field' or 'field1__field2' or
- # '-field1__field2__field', etc.
- for table, cols, order in self.find_ordering_name(field,
- self.query.get_meta(), default_order=asc):
- for col in cols:
- if (table, col) not in processed_pairs:
- elt = '%s.%s' % (qn(table), qn2(col))
- processed_pairs.add((table, col))
- if distinct and elt not in select_aliases:
- ordering_aliases.append(elt)
- result.append('%s %s' % (elt, order))
- group_by.append((elt, []))
- else:
- elt = qn2(col)
- if col not in self.query.extra_select:
- sql = "(%s) AS %s" % (self.query.extra[col][0], elt)
- ordering_aliases.append(sql)
- ordering_params.extend(self.query.extra[col][1])
- else:
- if distinct and col not in select_aliases:
- ordering_aliases.append(elt)
- ordering_params.extend(params)
- result.append('%s %s' % (elt, order))
- group_by.append(self.query.extra[col])
- self.ordering_aliases = ordering_aliases
- self.ordering_params = ordering_params
- return result, params, group_by
-
- def find_ordering_name(self, name, opts, alias=None, default_order='ASC',
- already_seen=None):
- """
- Returns the table alias (the name might be ambiguous, the alias will
- not be) and column name for ordering by the given 'name' parameter.
- The 'name' is of the form 'field1__field2__...__fieldN'.
- """
- name, order = get_order_dir(name, default_order)
- pieces = name.split(LOOKUP_SEP)
- field, cols, alias, joins, opts = self._setup_joins(pieces, opts, alias)
-
- # If we get to this point and the field is a relation to another model,
- # append the default ordering for that model.
- if field.rel and len(joins) > 1 and opts.ordering:
- # Firstly, avoid infinite loops.
- if not already_seen:
- already_seen = set()
- join_tuple = tuple([self.query.alias_map[j].table_name for j in joins])
- if join_tuple in already_seen:
- raise FieldError('Infinite loop caused by ordering.')
- already_seen.add(join_tuple)
-
- results = []
- for item in opts.ordering:
- results.extend(self.find_ordering_name(item, opts, alias,
- order, already_seen))
- return results
- cols, alias = self._final_join_removal(cols, alias)
- return [(alias, cols, order)]
-
- def _setup_joins(self, pieces, opts, alias):
- """
- A helper method for get_ordering and get_distinct. This method will
- call query.setup_joins, handle refcounts and then promote the joins.
-
- Note that get_ordering and get_distinct must produce same target
- columns on same input, as the prefixes of get_ordering and get_distinct
- must match. Executing SQL where this is not true is an error.
- """
- if not alias:
- alias = self.query.get_initial_alias()
- field, targets, opts, joins, _ = self.query.setup_joins(
- pieces, opts, alias)
- # We will later on need to promote those joins that were added to the
- # query afresh above.
- joins_to_promote = [j for j in joins if self.query.alias_refcount[j] < 2]
- alias = joins[-1]
- cols = [target.column for target in targets]
- if not field.rel:
- # To avoid inadvertent trimming of a necessary alias, use the
- # refcount to show that we are referencing a non-relation field on
- # the model.
- self.query.ref_alias(alias)
-
- # Must use left outer joins for nullable fields and their relations.
- # Ordering or distinct must not affect the returned set, and INNER
- # JOINS for nullable fields could do this.
- self.query.promote_joins(joins_to_promote)
- return field, cols, alias, joins, opts
-
- def _final_join_removal(self, cols, alias):
- """
- A helper method for get_distinct and get_ordering. This method will
- trim extra not-needed joins from the tail of the join chain.
-
- This is very similar to what is done in trim_joins, but we will
- trim LEFT JOINS here. It would be a good idea to consolidate this
- method and query.trim_joins().
- """
- if alias:
- while 1:
- join = self.query.alias_map[alias]
- lhs_cols, rhs_cols = zip(*[(lhs_col, rhs_col) for lhs_col, rhs_col in join.join_cols])
- if set(cols) != set(rhs_cols):
- break
-
- cols = [lhs_cols[rhs_cols.index(col)] for col in cols]
- self.query.unref_alias(alias)
- alias = join.lhs_alias
- return cols, alias
-
- def get_from_clause(self):
- """
- Returns a list of strings that are joined together to go after the
- "FROM" part of the query, as well as a list any extra parameters that
- need to be included. Sub-classes, can override this to create a
- from-clause via a "select".
-
- This should only be called after any SQL construction methods that
- might change the tables we need. This means the select columns,
- ordering and distinct must be done first.
- """
- result = []
- qn = self.quote_name_unless_alias
- qn2 = self.connection.ops.quote_name
- first = True
- from_params = []
- for alias in self.query.tables:
- if not self.query.alias_refcount[alias]:
- continue
- try:
- name, alias, join_type, lhs, join_cols, _, join_field = self.query.alias_map[alias]
- except KeyError:
- # Extra tables can end up in self.tables, but not in the
- # alias_map if they aren't in a join. That's OK. We skip them.
- continue
- alias_str = '' if alias == name else (' %s' % alias)
- if join_type and not first:
- extra_cond = join_field.get_extra_restriction(
- self.query.where_class, alias, lhs)
- if extra_cond:
- extra_sql, extra_params = extra_cond.as_sql(
- qn, self.connection)
- extra_sql = 'AND (%s)' % extra_sql
- from_params.extend(extra_params)
- else:
- extra_sql = ""
- result.append('%s %s%s ON ('
- % (join_type, qn(name), alias_str))
- for index, (lhs_col, rhs_col) in enumerate(join_cols):
- if index != 0:
- result.append(' AND ')
- result.append('%s.%s = %s.%s' %
- (qn(lhs), qn2(lhs_col), qn(alias), qn2(rhs_col)))
- result.append('%s)' % extra_sql)
- else:
- connector = '' if first else ', '
- result.append('%s%s%s' % (connector, qn(name), alias_str))
- first = False
- for t in self.query.extra_tables:
- alias, unused = self.query.table_alias(t)
- # Only add the alias if it's not already present (the table_alias()
- # calls increments the refcount, so an alias refcount of one means
- # this is the only reference.
- if alias not in self.query.alias_map or self.query.alias_refcount[alias] == 1:
- connector = '' if first else ', '
- result.append('%s%s' % (connector, qn(alias)))
- first = False
- return result, from_params
-
- def get_grouping(self, having_group_by, ordering_group_by):
- """
- Returns a tuple representing the SQL elements in the "group by" clause.
- """
- qn = self.quote_name_unless_alias
- result, params = [], []
- if self.query.group_by is not None:
- select_cols = self.query.select + self.query.related_select_cols
- # Just the column, not the fields.
- select_cols = [s[0] for s in select_cols]
- if (len(self.query.get_meta().concrete_fields) == len(self.query.select)
- and self.connection.features.allows_group_by_pk):
- self.query.group_by = [
- (self.query.get_meta().db_table, self.query.get_meta().pk.column)
- ]
- select_cols = []
- seen = set()
- cols = self.query.group_by + having_group_by + select_cols
- for col in cols:
- col_params = ()
- if isinstance(col, (list, tuple)):
- sql = '%s.%s' % (qn(col[0]), qn(col[1]))
- elif hasattr(col, 'as_sql'):
- sql, col_params = col.as_sql(qn, self.connection)
- else:
- sql = '(%s)' % str(col)
- if sql not in seen:
- result.append(sql)
- params.extend(col_params)
- seen.add(sql)
-
- # Still, we need to add all stuff in ordering (except if the backend can
- # group by just by PK).
- if ordering_group_by and not self.connection.features.allows_group_by_pk:
- for order, order_params in ordering_group_by:
- # Even if we have seen the same SQL string, it might have
- # different params, so, we add same SQL in "has params" case.
- if order not in seen or order_params:
- result.append(order)
- params.extend(order_params)
- seen.add(order)
-
- # Unconditionally add the extra_select items.
- for extra_select, extra_params in self.query.extra_select.values():
- sql = '(%s)' % str(extra_select)
- result.append(sql)
- params.extend(extra_params)
-
- return result, params
-
- def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
- requested=None, restricted=None, nullable=None):
- """
- Fill in the information needed for a select_related query. The current
- depth is measured as the number of connections away from the root model
- (for example, cur_depth=1 means we are looking at models with direct
- connections to the root model).
- """
- if not restricted and self.query.max_depth and cur_depth > self.query.max_depth:
- # We've recursed far enough; bail out.
- return
-
- if not opts:
- opts = self.query.get_meta()
- root_alias = self.query.get_initial_alias()
- self.query.related_select_cols = []
- only_load = self.query.get_loaded_field_names()
-
- # Setup for the case when only particular related fields should be
- # included in the related selection.
- if requested is None:
- if isinstance(self.query.select_related, dict):
- requested = self.query.select_related
- restricted = True
- else:
- restricted = False
-
- for f, model in opts.get_fields_with_model():
- # The get_fields_with_model() returns None for fields that live
- # in the field's local model. So, for those fields we want to use
- # the f.model - that is the field's local model.
- field_model = model or f.model
- if not select_related_descend(f, restricted, requested,
- only_load.get(field_model)):
- continue
- promote = nullable or f.null
- _, _, _, joins, _ = self.query.setup_joins(
- [f.name], opts, root_alias, outer_if_first=promote)
- alias = joins[-1]
- columns, _ = self.get_default_columns(start_alias=alias,
- opts=f.rel.to._meta, as_pairs=True)
- self.query.related_select_cols.extend(
- SelectInfo((col[0], col[1].column), col[1]) for col in columns)
- if restricted:
- next = requested.get(f.name, {})
- else:
- next = False
- new_nullable = f.null or promote
- self.fill_related_selections(f.rel.to._meta, alias, cur_depth + 1,
- next, restricted, new_nullable)
-
- if restricted:
- related_fields = [
- (o.field, o.model)
- for o in opts.get_all_related_objects()
- if o.field.unique
- ]
- for f, model in related_fields:
- if not select_related_descend(f, restricted, requested,
- only_load.get(model), reverse=True):
- continue
-
- _, _, _, joins, _ = self.query.setup_joins(
- [f.related_query_name()], opts, root_alias, outer_if_first=True)
- alias = joins[-1]
- from_parent = (opts.model if issubclass(model, opts.model)
- else None)
- columns, _ = self.get_default_columns(start_alias=alias,
- opts=model._meta, as_pairs=True, from_parent=from_parent)
- self.query.related_select_cols.extend(
- SelectInfo((col[0], col[1].column), col[1]) for col in columns)
- next = requested.get(f.related_query_name(), {})
- # Use True here because we are looking at the _reverse_ side of
- # the relation, which is always nullable.
- new_nullable = True
- self.fill_related_selections(model._meta, alias, cur_depth + 1,
- next, restricted, new_nullable)
-
- def deferred_to_columns(self):
- """
- Converts the self.deferred_loading data structure to mapping of table
- names to sets of column names which are to be loaded. Returns the
- dictionary.
- """
- columns = {}
- self.query.deferred_to_data(columns, self.query.deferred_to_columns_cb)
- return columns
-
- def results_iter(self):
- """
- Returns an iterator over the results from executing this query.
- """
- resolve_columns = hasattr(self, 'resolve_columns')
- fields = None
- has_aggregate_select = bool(self.query.aggregate_select)
- for rows in self.execute_sql(MULTI):
- for row in rows:
- if has_aggregate_select:
- loaded_fields = self.query.get_loaded_field_names().get(self.query.model, set()) or self.query.select
- aggregate_start = len(self.query.extra_select) + len(loaded_fields)
- aggregate_end = aggregate_start + len(self.query.aggregate_select)
- if resolve_columns:
- if fields is None:
- # We only set this up here because
- # related_select_cols isn't populated until
- # execute_sql() has been called.
-
- # We also include types of fields of related models that
- # will be included via select_related() for the benefit
- # of MySQL/MySQLdb when boolean fields are involved
- # (#15040).
-
- # This code duplicates the logic for the order of fields
- # found in get_columns(). It would be nice to clean this up.
- if self.query.select:
- fields = [f.field for f in self.query.select]
- elif self.query.default_cols:
- fields = self.query.get_meta().concrete_fields
- else:
- fields = []
- fields = fields + [f.field for f in self.query.related_select_cols]
-
- # If the field was deferred, exclude it from being passed
- # into `resolve_columns` because it wasn't selected.
- only_load = self.deferred_to_columns()
- if only_load:
- fields = [f for f in fields if f.model._meta.db_table not in only_load or
- f.column in only_load[f.model._meta.db_table]]
- if has_aggregate_select:
- # pad None in to fields for aggregates
- fields = fields[:aggregate_start] + [
- None for x in range(0, aggregate_end - aggregate_start)
- ] + fields[aggregate_start:]
- row = self.resolve_columns(row, fields)
-
- if has_aggregate_select:
- row = tuple(row[:aggregate_start]) + tuple([
- self.query.resolve_aggregate(value, aggregate, self.connection)
- for (alias, aggregate), value
- in zip(self.query.aggregate_select.items(), row[aggregate_start:aggregate_end])
- ]) + tuple(row[aggregate_end:])
-
- yield row
-
- def execute_sql(self, result_type=MULTI):
- """
- Run the query against the database and returns the result(s). The
- return value is a single data item if result_type is SINGLE, or an
- iterator over the results if the result_type is MULTI.
-
- result_type is either MULTI (use fetchmany() to retrieve all rows),
- SINGLE (only retrieve a single row), or None. In this last case, the
- cursor is returned if any query is executed, since it's used by
- subclasses such as InsertQuery). It's possible, however, that no query
- is needed, as the filters describe an empty set. In that case, None is
- returned, to avoid any unnecessary database interaction.
- """
- try:
- sql, params = self.as_sql()
- if not sql:
- raise EmptyResultSet
- except EmptyResultSet:
- if result_type == MULTI:
- return iter([])
- else:
- return
-
- cursor = self.connection.cursor()
- cursor.execute(sql, params)
-
- if not result_type:
- return cursor
- if result_type == SINGLE:
- if self.ordering_aliases:
- return cursor.fetchone()[:-len(self.ordering_aliases)]
- return cursor.fetchone()
-
- # The MULTI case.
- if self.ordering_aliases:
- result = order_modified_iter(cursor, len(self.ordering_aliases),
- self.connection.features.empty_fetchmany_value)
- else:
- result = iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)),
- self.connection.features.empty_fetchmany_value)
- if not self.connection.features.can_use_chunked_reads:
- # If we are using non-chunked reads, we return the same data
- # structure as normally, but ensure it is all read into memory
- # before going any further.
- return list(result)
- return result
-
- def as_subquery_condition(self, alias, columns, qn):
- qn2 = self.connection.ops.quote_name
- if len(columns) == 1:
- sql, params = self.as_sql()
- return '%s.%s IN (%s)' % (qn(alias), qn2(columns[0]), sql), params
-
- for index, select_col in enumerate(self.query.select):
- lhs = '%s.%s' % (qn(select_col.col[0]), qn2(select_col.col[1]))
- rhs = '%s.%s' % (qn(alias), qn2(columns[index]))
- self.query.where.add(
- QueryWrapper('%s = %s' % (lhs, rhs), []), 'AND')
-
- sql, params = self.as_sql()
- return 'EXISTS (%s)' % sql, params
-
-
-class SQLInsertCompiler(SQLCompiler):
-
- def __init__(self, *args, **kwargs):
- self.return_id = False
- super(SQLInsertCompiler, self).__init__(*args, **kwargs)
-
- def placeholder(self, field, val):
- if field is None:
- # A field value of None means the value is raw.
- return val
- elif hasattr(field, 'get_placeholder'):
- # Some fields (e.g. geo fields) need special munging before
- # they can be inserted.
- return field.get_placeholder(val, self.connection)
- else:
- # Return the common case for the placeholder
- return '%s'
-
- def as_sql(self):
- # We don't need quote_name_unless_alias() here, since these are all
- # going to be column names (so we can avoid the extra overhead).
- qn = self.connection.ops.quote_name
- opts = self.query.get_meta()
- result = ['INSERT INTO %s' % qn(opts.db_table)]
-
- has_fields = bool(self.query.fields)
- fields = self.query.fields if has_fields else [opts.pk]
- result.append('(%s)' % ', '.join([qn(f.column) for f in fields]))
-
- if has_fields:
- params = values = [
- [
- f.get_db_prep_save(getattr(obj, f.attname) if self.query.raw else f.pre_save(obj, True), connection=self.connection)
- for f in fields
- ]
- for obj in self.query.objs
- ]
- else:
- values = [[self.connection.ops.pk_default_value()] for obj in self.query.objs]
- params = [[]]
- fields = [None]
- can_bulk = (not any(hasattr(field, "get_placeholder") for field in fields) and
- not self.return_id and self.connection.features.has_bulk_insert)
-
- if can_bulk:
- placeholders = [["%s"] * len(fields)]
- else:
- placeholders = [
- [self.placeholder(field, v) for field, v in zip(fields, val)]
- for val in values
- ]
- # Oracle Spatial needs to remove some values due to #10888
- params = self.connection.ops.modify_insert_params(placeholders, params)
- if self.return_id and self.connection.features.can_return_id_from_insert:
- params = params[0]
- col = "%s.%s" % (qn(opts.db_table), qn(opts.pk.column))
- result.append("VALUES (%s)" % ", ".join(placeholders[0]))
- r_fmt, r_params = self.connection.ops.return_insert_id()
- # Skip empty r_fmt to allow subclasses to customize behaviour for
- # 3rd party backends. Refs #19096.
- if r_fmt:
- result.append(r_fmt % col)
- params += r_params
- return [(" ".join(result), tuple(params))]
- if can_bulk:
- result.append(self.connection.ops.bulk_insert_sql(fields, len(values)))
- return [(" ".join(result), tuple([v for val in values for v in val]))]
- else:
- return [
- (" ".join(result + ["VALUES (%s)" % ", ".join(p)]), vals)
- for p, vals in zip(placeholders, params)
- ]
-
- def execute_sql(self, return_id=False):
- assert not (return_id and len(self.query.objs) != 1)
- self.return_id = return_id
- cursor = self.connection.cursor()
- for sql, params in self.as_sql():
- cursor.execute(sql, params)
- if not (return_id and cursor):
- return
- if self.connection.features.can_return_id_from_insert:
- return self.connection.ops.fetch_returned_insert_id(cursor)
- return self.connection.ops.last_insert_id(cursor,
- self.query.get_meta().db_table, self.query.get_meta().pk.column)
-
-
-class SQLDeleteCompiler(SQLCompiler):
- def as_sql(self):
- """
- Creates the SQL for this query. Returns the SQL string and list of
- parameters.
- """
- assert len(self.query.tables) == 1, \
- "Can only delete from one table at a time."
- qn = self.quote_name_unless_alias
- result = ['DELETE FROM %s' % qn(self.query.tables[0])]
- where, params = self.query.where.as_sql(qn=qn, connection=self.connection)
- if where:
- result.append('WHERE %s' % where)
- return ' '.join(result), tuple(params)
-
-class SQLUpdateCompiler(SQLCompiler):
- def as_sql(self):
- """
- Creates the SQL for this query. Returns the SQL string and list of
- parameters.
- """
- self.pre_sql_setup()
- if not self.query.values:
- return '', ()
- table = self.query.tables[0]
- qn = self.quote_name_unless_alias
- result = ['UPDATE %s' % qn(table)]
- result.append('SET')
- values, update_params = [], []
- for field, model, val in self.query.values:
- if hasattr(val, 'prepare_database_save'):
- val = val.prepare_database_save(field)
- else:
- val = field.get_db_prep_save(val, connection=self.connection)
-
- # Getting the placeholder for the field.
- if hasattr(field, 'get_placeholder'):
- placeholder = field.get_placeholder(val, self.connection)
- else:
- placeholder = '%s'
-
- if hasattr(val, 'evaluate'):
- val = SQLEvaluator(val, self.query, allow_joins=False)
- name = field.column
- if hasattr(val, 'as_sql'):
- sql, params = val.as_sql(qn, self.connection)
- values.append('%s = %s' % (qn(name), sql))
- update_params.extend(params)
- elif val is not None:
- values.append('%s = %s' % (qn(name), placeholder))
- update_params.append(val)
- else:
- values.append('%s = NULL' % qn(name))
- if not values:
- return '', ()
- result.append(', '.join(values))
- where, params = self.query.where.as_sql(qn=qn, connection=self.connection)
- if where:
- result.append('WHERE %s' % where)
- return ' '.join(result), tuple(update_params + params)
-
- def execute_sql(self, result_type):
- """
- Execute the specified update. Returns the number of rows affected by
- the primary update query. The "primary update query" is the first
- non-empty query that is executed. Row counts for any subsequent,
- related queries are not available.
- """
- cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
- rows = cursor.rowcount if cursor else 0
- is_empty = cursor is None
- del cursor
- for query in self.query.get_related_updates():
- aux_rows = query.get_compiler(self.using).execute_sql(result_type)
- if is_empty:
- rows = aux_rows
- is_empty = False
- return rows
-
- def pre_sql_setup(self):
- """
- If the update depends on results from other tables, we need to do some
- munging of the "where" conditions to match the format required for
- (portable) SQL updates. That is done here.
-
- Further, if we are going to be running multiple updates, we pull out
- the id values to update at this point so that they don't change as a
- result of the progressive updates.
- """
- self.query.select_related = False
- self.query.clear_ordering(True)
- super(SQLUpdateCompiler, self).pre_sql_setup()
- count = self.query.count_active_tables()
- if not self.query.related_updates and count == 1:
- return
-
- # We need to use a sub-select in the where clause to filter on things
- # from other tables.
- query = self.query.clone(klass=Query)
- query.bump_prefix()
- query.extra = {}
- query.select = []
- query.add_fields([query.get_meta().pk.name])
- # Recheck the count - it is possible that fiddling with the select
- # fields above removes tables from the query. Refs #18304.
- count = query.count_active_tables()
- if not self.query.related_updates and count == 1:
- return
-
- must_pre_select = count > 1 and not self.connection.features.update_can_self_select
-
- # Now we adjust the current query: reset the where clause and get rid
- # of all the tables we don't need (since they're in the sub-select).
- self.query.where = self.query.where_class()
- if self.query.related_updates or must_pre_select:
- # Either we're using the idents in multiple update queries (so
- # don't want them to change), or the db backend doesn't support
- # selecting from the updating table (e.g. MySQL).
- idents = []
- for rows in query.get_compiler(self.using).execute_sql(MULTI):
- idents.extend([r[0] for r in rows])
- self.query.add_filter(('pk__in', idents))
- self.query.related_ids = idents
- else:
- # The fast path. Filters and updates in one query.
- self.query.add_filter(('pk__in', query))
- for alias in self.query.tables[1:]:
- self.query.alias_refcount[alias] = 0
-
-class SQLAggregateCompiler(SQLCompiler):
- def as_sql(self, qn=None):
- """
- Creates the SQL for this query. Returns the SQL string and list of
- parameters.
- """
- if qn is None:
- qn = self.quote_name_unless_alias
-
- sql, params = [], []
- for aggregate in self.query.aggregate_select.values():
- agg_sql, agg_params = aggregate.as_sql(qn, self.connection)
- sql.append(agg_sql)
- params.extend(agg_params)
- sql = ', '.join(sql)
- params = tuple(params)
-
- sql = 'SELECT %s FROM (%s) subquery' % (sql, self.query.subquery)
- params = params + self.query.sub_params
- return sql, params
-
-class SQLDateCompiler(SQLCompiler):
- def results_iter(self):
- """
- Returns an iterator over the results from executing this query.
- """
- resolve_columns = hasattr(self, 'resolve_columns')
- if resolve_columns:
- from django.db.models.fields import DateField
- fields = [DateField()]
- else:
- from django.db.backends.util import typecast_date
- needs_string_cast = self.connection.features.needs_datetime_string_cast
-
- offset = len(self.query.extra_select)
- for rows in self.execute_sql(MULTI):
- for row in rows:
- date = row[offset]
- if resolve_columns:
- date = self.resolve_columns(row, fields)[offset]
- elif needs_string_cast:
- date = typecast_date(str(date))
- if isinstance(date, datetime.datetime):
- date = date.date()
- yield date
-
-class SQLDateTimeCompiler(SQLCompiler):
- def results_iter(self):
- """
- Returns an iterator over the results from executing this query.
- """
- resolve_columns = hasattr(self, 'resolve_columns')
- if resolve_columns:
- from django.db.models.fields import DateTimeField
- fields = [DateTimeField()]
- else:
- from django.db.backends.util import typecast_timestamp
- needs_string_cast = self.connection.features.needs_datetime_string_cast
-
- offset = len(self.query.extra_select)
- for rows in self.execute_sql(MULTI):
- for row in rows:
- datetime = row[offset]
- if resolve_columns:
- datetime = self.resolve_columns(row, fields)[offset]
- elif needs_string_cast:
- datetime = typecast_timestamp(str(datetime))
- # Datetimes are artifically returned in UTC on databases that
- # don't support time zone. Restore the zone used in the query.
- if settings.USE_TZ:
- if datetime is None:
- raise ValueError("Database returned an invalid value "
- "in QuerySet.datetimes(). Are time zone "
- "definitions for your database and pytz installed?")
- datetime = datetime.replace(tzinfo=None)
- datetime = timezone.make_aware(datetime, self.query.tzinfo)
- yield datetime
-
-def order_modified_iter(cursor, trim, sentinel):
- """
- Yields blocks of rows from a cursor. We use this iterator in the special
- case when extra output columns have been added to support ordering
- requirements. We must trim those extra columns before anything else can use
- the results, since they're only needed to make the SQL valid.
- """
- for rows in iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)),
- sentinel):
- yield [r[:-trim] for r in rows]
diff --git a/lib/python2.7/site-packages/django/db/models/sql/constants.py b/lib/python2.7/site-packages/django/db/models/sql/constants.py
deleted file mode 100644
index 904f7b2..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/constants.py
+++ /dev/null
@@ -1,41 +0,0 @@
-"""
-Constants specific to the SQL storage portion of the ORM.
-"""
-
-from collections import namedtuple
-import re
-
-# Valid query types (a set is used for speedy lookups). These are (currently)
-# considered SQL-specific; other storage systems may choose to use different
-# lookup types.
-QUERY_TERMS = set([
- 'exact', 'iexact', 'contains', 'icontains', 'gt', 'gte', 'lt', 'lte', 'in',
- 'startswith', 'istartswith', 'endswith', 'iendswith', 'range', 'year',
- 'month', 'day', 'week_day', 'hour', 'minute', 'second', 'isnull', 'search',
- 'regex', 'iregex',
-])
-
-# Size of each "chunk" for get_iterator calls.
-# Larger values are slightly faster at the expense of more storage space.
-GET_ITERATOR_CHUNK_SIZE = 100
-
-# Namedtuples for sql.* internal use.
-
-# Join lists (indexes into the tuples that are values in the alias_map
-# dictionary in the Query class).
-JoinInfo = namedtuple('JoinInfo',
- 'table_name rhs_alias join_type lhs_alias '
- 'join_cols nullable join_field')
-
-# Pairs of column clauses to select, and (possibly None) field for the clause.
-SelectInfo = namedtuple('SelectInfo', 'col field')
-
-# How many results to expect from a cursor.execute call
-MULTI = 'multi'
-SINGLE = 'single'
-
-ORDER_PATTERN = re.compile(r'\?|[-+]?[.\w]+$')
-ORDER_DIR = {
- 'ASC': ('ASC', 'DESC'),
- 'DESC': ('DESC', 'ASC'),
-}
diff --git a/lib/python2.7/site-packages/django/db/models/sql/datastructures.py b/lib/python2.7/site-packages/django/db/models/sql/datastructures.py
deleted file mode 100644
index daaabbe..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/datastructures.py
+++ /dev/null
@@ -1,62 +0,0 @@
-"""
-Useful auxilliary data structures for query construction. Not useful outside
-the SQL domain.
-"""
-
-class EmptyResultSet(Exception):
- pass
-
-class MultiJoin(Exception):
- """
- Used by join construction code to indicate the point at which a
- multi-valued join was attempted (if the caller wants to treat that
- exceptionally).
- """
- def __init__(self, names_pos, path_with_names):
- self.level = names_pos
- # The path travelled, this includes the path to the multijoin.
- self.names_with_path = path_with_names
-
-class Empty(object):
- pass
-
-class RawValue(object):
- def __init__(self, value):
- self.value = value
-
-class Date(object):
- """
- Add a date selection column.
- """
- def __init__(self, col, lookup_type):
- self.col = col
- self.lookup_type = lookup_type
-
- def relabeled_clone(self, change_map):
- return self.__class__((change_map.get(self.col[0], self.col[0]), self.col[1]))
-
- def as_sql(self, qn, connection):
- if isinstance(self.col, (list, tuple)):
- col = '%s.%s' % tuple([qn(c) for c in self.col])
- else:
- col = self.col
- return connection.ops.date_trunc_sql(self.lookup_type, col), []
-
-class DateTime(object):
- """
- Add a datetime selection column.
- """
- def __init__(self, col, lookup_type, tzname):
- self.col = col
- self.lookup_type = lookup_type
- self.tzname = tzname
-
- def relabeled_clone(self, change_map):
- return self.__class__((change_map.get(self.col[0], self.col[0]), self.col[1]))
-
- def as_sql(self, qn, connection):
- if isinstance(self.col, (list, tuple)):
- col = '%s.%s' % tuple([qn(c) for c in self.col])
- else:
- col = self.col
- return connection.ops.datetime_trunc_sql(self.lookup_type, col, self.tzname)
diff --git a/lib/python2.7/site-packages/django/db/models/sql/expressions.py b/lib/python2.7/site-packages/django/db/models/sql/expressions.py
deleted file mode 100644
index 31e0899..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/expressions.py
+++ /dev/null
@@ -1,117 +0,0 @@
-from django.core.exceptions import FieldError
-from django.db.models.constants import LOOKUP_SEP
-from django.db.models.fields import FieldDoesNotExist
-import copy
-
-class SQLEvaluator(object):
- def __init__(self, expression, query, allow_joins=True, reuse=None):
- self.expression = expression
- self.opts = query.get_meta()
- self.reuse = reuse
- self.cols = []
- self.expression.prepare(self, query, allow_joins)
-
- def relabeled_clone(self, change_map):
- clone = copy.copy(self)
- clone.cols = []
- for node, col in self.cols:
- if hasattr(col, 'relabeled_clone'):
- clone.cols.append((node, col.relabeled_clone(change_map)))
- else:
- clone.cols.append((node,
- (change_map.get(col[0], col[0]), col[1])))
- return clone
-
- def get_cols(self):
- cols = []
- for node, col in self.cols:
- if hasattr(node, 'get_cols'):
- cols.extend(node.get_cols())
- elif isinstance(col, tuple):
- cols.append(col)
- return cols
-
- def prepare(self):
- return self
-
- def as_sql(self, qn, connection):
- return self.expression.evaluate(self, qn, connection)
-
- #####################################################
- # Vistor methods for initial expression preparation #
- #####################################################
-
- def prepare_node(self, node, query, allow_joins):
- for child in node.children:
- if hasattr(child, 'prepare'):
- child.prepare(self, query, allow_joins)
-
- def prepare_leaf(self, node, query, allow_joins):
- if not allow_joins and LOOKUP_SEP in node.name:
- raise FieldError("Joined field references are not permitted in this query")
-
- field_list = node.name.split(LOOKUP_SEP)
- if node.name in query.aggregates:
- self.cols.append((node, query.aggregate_select[node.name]))
- else:
- try:
- field, sources, opts, join_list, path = query.setup_joins(
- field_list, query.get_meta(),
- query.get_initial_alias(), self.reuse)
- targets, _, join_list = query.trim_joins(sources, join_list, path)
- if self.reuse is not None:
- self.reuse.update(join_list)
- for t in targets:
- self.cols.append((node, (join_list[-1], t.column)))
- except FieldDoesNotExist:
- raise FieldError("Cannot resolve keyword %r into field. "
- "Choices are: %s" % (self.name,
- [f.name for f in self.opts.fields]))
-
- ##################################################
- # Vistor methods for final expression evaluation #
- ##################################################
-
- def evaluate_node(self, node, qn, connection):
- expressions = []
- expression_params = []
- for child in node.children:
- if hasattr(child, 'evaluate'):
- sql, params = child.evaluate(self, qn, connection)
- else:
- sql, params = '%s', (child,)
-
- if len(getattr(child, 'children', [])) > 1:
- format = '(%s)'
- else:
- format = '%s'
-
- if sql:
- expressions.append(format % sql)
- expression_params.extend(params)
-
- return connection.ops.combine_expression(node.connector, expressions), expression_params
-
- def evaluate_leaf(self, node, qn, connection):
- col = None
- for n, c in self.cols:
- if n is node:
- col = c
- break
- if col is None:
- raise ValueError("Given node not found")
- if hasattr(col, 'as_sql'):
- return col.as_sql(qn, connection)
- else:
- return '%s.%s' % (qn(col[0]), qn(col[1])), []
-
- def evaluate_date_modifier_node(self, node, qn, connection):
- timedelta = node.children.pop()
- sql, params = self.evaluate_node(node, qn, connection)
- node.children.append(timedelta)
-
- if timedelta.days == 0 and timedelta.seconds == 0 and \
- timedelta.microseconds == 0:
- return sql, params
-
- return connection.ops.date_interval_sql(sql, node.connector, timedelta), params
diff --git a/lib/python2.7/site-packages/django/db/models/sql/query.py b/lib/python2.7/site-packages/django/db/models/sql/query.py
deleted file mode 100644
index 7868c19..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/query.py
+++ /dev/null
@@ -1,1922 +0,0 @@
-"""
-Create SQL statements for QuerySets.
-
-The code in here encapsulates all of the SQL construction so that QuerySets
-themselves do not have to (and could be backed by things other than SQL
-databases). The abstraction barrier only works one way: this module has to know
-all about the internals of models in order to get the information it needs.
-"""
-
-import copy
-
-from django.utils.datastructures import SortedDict
-from django.utils.encoding import force_text
-from django.utils.tree import Node
-from django.utils import six
-from django.db import connections, DEFAULT_DB_ALIAS
-from django.db.models.constants import LOOKUP_SEP
-from django.db.models.aggregates import refs_aggregate
-from django.db.models.expressions import ExpressionNode
-from django.db.models.fields import FieldDoesNotExist
-from django.db.models.related import PathInfo
-from django.db.models.sql import aggregates as base_aggregates_module
-from django.db.models.sql.constants import (QUERY_TERMS, ORDER_DIR, SINGLE,
- ORDER_PATTERN, JoinInfo, SelectInfo)
-from django.db.models.sql.datastructures import EmptyResultSet, Empty, MultiJoin
-from django.db.models.sql.expressions import SQLEvaluator
-from django.db.models.sql.where import (WhereNode, Constraint, EverythingNode,
- ExtraWhere, AND, OR, EmptyWhere)
-from django.core.exceptions import FieldError
-
-__all__ = ['Query', 'RawQuery']
-
-
-class RawQuery(object):
- """
- A single raw SQL query
- """
-
- def __init__(self, sql, using, params=None):
- self.params = params or ()
- self.sql = sql
- self.using = using
- self.cursor = None
-
- # Mirror some properties of a normal query so that
- # the compiler can be used to process results.
- self.low_mark, self.high_mark = 0, None # Used for offset/limit
- self.extra_select = {}
- self.aggregate_select = {}
-
- def clone(self, using):
- return RawQuery(self.sql, using, params=self.params)
-
- def convert_values(self, value, field, connection):
- """Convert the database-returned value into a type that is consistent
- across database backends.
-
- By default, this defers to the underlying backend operations, but
- it can be overridden by Query classes for specific backends.
- """
- return connection.ops.convert_values(value, field)
-
- def get_columns(self):
- if self.cursor is None:
- self._execute_query()
- converter = connections[self.using].introspection.table_name_converter
- return [converter(column_meta[0])
- for column_meta in self.cursor.description]
-
- def __iter__(self):
- # Always execute a new query for a new iterator.
- # This could be optimized with a cache at the expense of RAM.
- self._execute_query()
- if not connections[self.using].features.can_use_chunked_reads:
- # If the database can't use chunked reads we need to make sure we
- # evaluate the entire query up front.
- result = list(self.cursor)
- else:
- result = self.cursor
- return iter(result)
-
- def __repr__(self):
- return "<RawQuery: %r>" % (self.sql % tuple(self.params))
-
- def _execute_query(self):
- self.cursor = connections[self.using].cursor()
- self.cursor.execute(self.sql, self.params)
-
-
-class Query(object):
- """
- A single SQL query.
- """
- # SQL join types. These are part of the class because their string forms
- # vary from database to database and can be customised by a subclass.
- INNER = 'INNER JOIN'
- LOUTER = 'LEFT OUTER JOIN'
-
- alias_prefix = 'T'
- query_terms = QUERY_TERMS
- aggregates_module = base_aggregates_module
-
- compiler = 'SQLCompiler'
-
- def __init__(self, model, where=WhereNode):
- self.model = model
- self.alias_refcount = {}
- # alias_map is the most important data structure regarding joins.
- # It's used for recording which joins exist in the query and what
- # type they are. The key is the alias of the joined table (possibly
- # the table name) and the value is JoinInfo from constants.py.
- self.alias_map = {}
- self.table_map = {} # Maps table names to list of aliases.
- self.join_map = {}
- self.default_cols = True
- self.default_ordering = True
- self.standard_ordering = True
- self.used_aliases = set()
- self.filter_is_sticky = False
- self.included_inherited_models = {}
-
- # SQL-related attributes
- # Select and related select clauses as SelectInfo instances.
- # The select is used for cases where we want to set up the select
- # clause to contain other than default fields (values(), annotate(),
- # subqueries...)
- self.select = []
- # The related_select_cols is used for columns needed for
- # select_related - this is populated in compile stage.
- self.related_select_cols = []
- self.tables = [] # Aliases in the order they are created.
- self.where = where()
- self.where_class = where
- self.group_by = None
- self.having = where()
- self.order_by = []
- self.low_mark, self.high_mark = 0, None # Used for offset/limit
- self.distinct = False
- self.distinct_fields = []
- self.select_for_update = False
- self.select_for_update_nowait = False
- self.select_related = False
-
- # SQL aggregate-related attributes
- self.aggregates = SortedDict() # Maps alias -> SQL aggregate function
- self.aggregate_select_mask = None
- self._aggregate_select_cache = None
-
- # Arbitrary maximum limit for select_related. Prevents infinite
- # recursion. Can be changed by the depth parameter to select_related().
- self.max_depth = 5
-
- # These are for extensions. The contents are more or less appended
- # verbatim to the appropriate clause.
- self.extra = SortedDict() # Maps col_alias -> (col_sql, params).
- self.extra_select_mask = None
- self._extra_select_cache = None
-
- self.extra_tables = ()
- self.extra_order_by = ()
-
- # A tuple that is a set of model field names and either True, if these
- # are the fields to defer, or False if these are the only fields to
- # load.
- self.deferred_loading = (set(), True)
-
- def __str__(self):
- """
- Returns the query as a string of SQL with the parameter values
- substituted in (use sql_with_params() to see the unsubstituted string).
-
- Parameter values won't necessarily be quoted correctly, since that is
- done by the database interface at execution time.
- """
- sql, params = self.sql_with_params()
- return sql % params
-
- def sql_with_params(self):
- """
- Returns the query as an SQL string and the parameters that will be
- subsituted into the query.
- """
- return self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
-
- def __deepcopy__(self, memo):
- result = self.clone(memo=memo)
- memo[id(self)] = result
- return result
-
- def prepare(self):
- return self
-
- def get_compiler(self, using=None, connection=None):
- if using is None and connection is None:
- raise ValueError("Need either using or connection")
- if using:
- connection = connections[using]
-
- # Check that the compiler will be able to execute the query
- for alias, aggregate in self.aggregate_select.items():
- connection.ops.check_aggregate_support(aggregate)
-
- return connection.ops.compiler(self.compiler)(self, connection, using)
-
- def get_meta(self):
- """
- Returns the Options instance (the model._meta) from which to start
- processing. Normally, this is self.model._meta, but it can be changed
- by subclasses.
- """
- return self.model._meta
-
- def clone(self, klass=None, memo=None, **kwargs):
- """
- Creates a copy of the current instance. The 'kwargs' parameter can be
- used by clients to update attributes after copying has taken place.
- """
- obj = Empty()
- obj.__class__ = klass or self.__class__
- obj.model = self.model
- obj.alias_refcount = self.alias_refcount.copy()
- obj.alias_map = self.alias_map.copy()
- obj.table_map = self.table_map.copy()
- obj.join_map = self.join_map.copy()
- obj.default_cols = self.default_cols
- obj.default_ordering = self.default_ordering
- obj.standard_ordering = self.standard_ordering
- obj.included_inherited_models = self.included_inherited_models.copy()
- obj.select = self.select[:]
- obj.related_select_cols = []
- obj.tables = self.tables[:]
- obj.where = self.where.clone()
- obj.where_class = self.where_class
- if self.group_by is None:
- obj.group_by = None
- else:
- obj.group_by = self.group_by[:]
- obj.having = self.having.clone()
- obj.order_by = self.order_by[:]
- obj.low_mark, obj.high_mark = self.low_mark, self.high_mark
- obj.distinct = self.distinct
- obj.distinct_fields = self.distinct_fields[:]
- obj.select_for_update = self.select_for_update
- obj.select_for_update_nowait = self.select_for_update_nowait
- obj.select_related = self.select_related
- obj.related_select_cols = []
- obj.aggregates = self.aggregates.copy()
- if self.aggregate_select_mask is None:
- obj.aggregate_select_mask = None
- else:
- obj.aggregate_select_mask = self.aggregate_select_mask.copy()
- # _aggregate_select_cache cannot be copied, as doing so breaks the
- # (necessary) state in which both aggregates and
- # _aggregate_select_cache point to the same underlying objects.
- # It will get re-populated in the cloned queryset the next time it's
- # used.
- obj._aggregate_select_cache = None
- obj.max_depth = self.max_depth
- obj.extra = self.extra.copy()
- if self.extra_select_mask is None:
- obj.extra_select_mask = None
- else:
- obj.extra_select_mask = self.extra_select_mask.copy()
- if self._extra_select_cache is None:
- obj._extra_select_cache = None
- else:
- obj._extra_select_cache = self._extra_select_cache.copy()
- obj.extra_tables = self.extra_tables
- obj.extra_order_by = self.extra_order_by
- obj.deferred_loading = copy.copy(self.deferred_loading[0]), self.deferred_loading[1]
- if self.filter_is_sticky and self.used_aliases:
- obj.used_aliases = self.used_aliases.copy()
- else:
- obj.used_aliases = set()
- obj.filter_is_sticky = False
-
- obj.__dict__.update(kwargs)
- if hasattr(obj, '_setup_query'):
- obj._setup_query()
- return obj
-
- def convert_values(self, value, field, connection):
- """Convert the database-returned value into a type that is consistent
- across database backends.
-
- By default, this defers to the underlying backend operations, but
- it can be overridden by Query classes for specific backends.
- """
- return connection.ops.convert_values(value, field)
-
- def resolve_aggregate(self, value, aggregate, connection):
- """Resolve the value of aggregates returned by the database to
- consistent (and reasonable) types.
-
- This is required because of the predisposition of certain backends
- to return Decimal and long types when they are not needed.
- """
- if value is None:
- if aggregate.is_ordinal:
- return 0
- # Return None as-is
- return value
- elif aggregate.is_ordinal:
- # Any ordinal aggregate (e.g., count) returns an int
- return int(value)
- elif aggregate.is_computed:
- # Any computed aggregate (e.g., avg) returns a float
- return float(value)
- else:
- # Return value depends on the type of the field being processed.
- return self.convert_values(value, aggregate.field, connection)
-
- def get_aggregation(self, using):
- """
- Returns the dictionary with the values of the existing aggregations.
- """
- if not self.aggregate_select:
- return {}
-
- # If there is a group by clause, aggregating does not add useful
- # information but retrieves only the first row. Aggregate
- # over the subquery instead.
- if self.group_by is not None:
- from django.db.models.sql.subqueries import AggregateQuery
- query = AggregateQuery(self.model)
-
- obj = self.clone()
-
- # Remove any aggregates marked for reduction from the subquery
- # and move them to the outer AggregateQuery.
- for alias, aggregate in self.aggregate_select.items():
- if aggregate.is_summary:
- query.aggregate_select[alias] = aggregate
- del obj.aggregate_select[alias]
-
- try:
- query.add_subquery(obj, using)
- except EmptyResultSet:
- return dict(
- (alias, None)
- for alias in query.aggregate_select
- )
- else:
- query = self
- self.select = []
- self.default_cols = False
- self.extra = {}
- self.remove_inherited_models()
-
- query.clear_ordering(True)
- query.clear_limits()
- query.select_for_update = False
- query.select_related = False
- query.related_select_cols = []
-
- result = query.get_compiler(using).execute_sql(SINGLE)
- if result is None:
- result = [None for q in query.aggregate_select.items()]
-
- return dict([
- (alias, self.resolve_aggregate(val, aggregate, connection=connections[using]))
- for (alias, aggregate), val
- in zip(query.aggregate_select.items(), result)
- ])
-
- def get_count(self, using):
- """
- Performs a COUNT() query using the current filter constraints.
- """
- obj = self.clone()
- if len(self.select) > 1 or self.aggregate_select or (self.distinct and self.distinct_fields):
- # If a select clause exists, then the query has already started to
- # specify the columns that are to be returned.
- # In this case, we need to use a subquery to evaluate the count.
- from django.db.models.sql.subqueries import AggregateQuery
- subquery = obj
- subquery.clear_ordering(True)
- subquery.clear_limits()
-
- obj = AggregateQuery(obj.model)
- try:
- obj.add_subquery(subquery, using=using)
- except EmptyResultSet:
- # add_subquery evaluates the query, if it's an EmptyResultSet
- # then there are can be no results, and therefore there the
- # count is obviously 0
- return 0
-
- obj.add_count_column()
- number = obj.get_aggregation(using=using)[None]
-
- # Apply offset and limit constraints manually, since using LIMIT/OFFSET
- # in SQL (in variants that provide them) doesn't change the COUNT
- # output.
- number = max(0, number - self.low_mark)
- if self.high_mark is not None:
- number = min(number, self.high_mark - self.low_mark)
-
- return number
-
- def has_results(self, using):
- q = self.clone()
- q.clear_select_clause()
- q.add_extra({'a': 1}, None, None, None, None, None)
- q.set_extra_mask(['a'])
- q.clear_ordering(True)
- q.set_limits(high=1)
- compiler = q.get_compiler(using=using)
- return bool(compiler.execute_sql(SINGLE))
-
- def combine(self, rhs, connector):
- """
- Merge the 'rhs' query into the current one (with any 'rhs' effects
- being applied *after* (that is, "to the right of") anything in the
- current query. 'rhs' is not modified during a call to this function.
-
- The 'connector' parameter describes how to connect filters from the
- 'rhs' query.
- """
- assert self.model == rhs.model, \
- "Cannot combine queries on two different base models."
- assert self.can_filter(), \
- "Cannot combine queries once a slice has been taken."
- assert self.distinct == rhs.distinct, \
- "Cannot combine a unique query with a non-unique query."
- assert self.distinct_fields == rhs.distinct_fields, \
- "Cannot combine queries with different distinct fields."
-
- self.remove_inherited_models()
- # Work out how to relabel the rhs aliases, if necessary.
- change_map = {}
- conjunction = (connector == AND)
-
- # Determine which existing joins can be reused. When combining the
- # query with AND we must recreate all joins for m2m filters. When
- # combining with OR we can reuse joins. The reason is that in AND
- # case a single row can't fulfill a condition like:
- # revrel__col=1 & revrel__col=2
- # But, there might be two different related rows matching this
- # condition. In OR case a single True is enough, so single row is
- # enough, too.
- #
- # Note that we will be creating duplicate joins for non-m2m joins in
- # the AND case. The results will be correct but this creates too many
- # joins. This is something that could be fixed later on.
- reuse = set() if conjunction else set(self.tables)
- # Base table must be present in the query - this is the same
- # table on both sides.
- self.get_initial_alias()
- # Now, add the joins from rhs query into the new query (skipping base
- # table).
- for alias in rhs.tables[1:]:
- table, _, join_type, lhs, join_cols, nullable, join_field = rhs.alias_map[alias]
- promote = (join_type == self.LOUTER)
- # If the left side of the join was already relabeled, use the
- # updated alias.
- lhs = change_map.get(lhs, lhs)
- new_alias = self.join(
- (lhs, table, join_cols), reuse=reuse,
- outer_if_first=not conjunction, nullable=nullable,
- join_field=join_field)
- if promote:
- self.promote_joins([new_alias])
- # We can't reuse the same join again in the query. If we have two
- # distinct joins for the same connection in rhs query, then the
- # combined query must have two joins, too.
- reuse.discard(new_alias)
- change_map[alias] = new_alias
- if not rhs.alias_refcount[alias]:
- # The alias was unused in the rhs query. Unref it so that it
- # will be unused in the new query, too. We have to add and
- # unref the alias so that join promotion has information of
- # the join type for the unused alias.
- self.unref_alias(new_alias)
-
- # So that we don't exclude valid results in an OR query combination,
- # all joins exclusive to either the lhs or the rhs must be converted
- # to an outer join. RHS joins were already set to outer joins above,
- # so check which joins were used only in the lhs query.
- if not conjunction:
- rhs_used_joins = set(change_map.values())
- to_promote = [alias for alias in self.tables
- if alias not in rhs_used_joins]
- self.promote_joins(to_promote, True)
-
- # Now relabel a copy of the rhs where-clause and add it to the current
- # one.
- if rhs.where:
- w = rhs.where.clone()
- w.relabel_aliases(change_map)
- if not self.where:
- # Since 'self' matches everything, add an explicit "include
- # everything" where-constraint so that connections between the
- # where clauses won't exclude valid results.
- self.where.add(EverythingNode(), AND)
- elif self.where:
- # rhs has an empty where clause.
- w = self.where_class()
- w.add(EverythingNode(), AND)
- else:
- w = self.where_class()
- self.where.add(w, connector)
-
- # Selection columns and extra extensions are those provided by 'rhs'.
- self.select = []
- for col, field in rhs.select:
- if isinstance(col, (list, tuple)):
- new_col = change_map.get(col[0], col[0]), col[1]
- self.select.append(SelectInfo(new_col, field))
- else:
- new_col = col.relabeled_clone(change_map)
- self.select.append(SelectInfo(new_col, field))
-
- if connector == OR:
- # It would be nice to be able to handle this, but the queries don't
- # really make sense (or return consistent value sets). Not worth
- # the extra complexity when you can write a real query instead.
- if self.extra and rhs.extra:
- raise ValueError("When merging querysets using 'or', you "
- "cannot have extra(select=...) on both sides.")
- self.extra.update(rhs.extra)
- extra_select_mask = set()
- if self.extra_select_mask is not None:
- extra_select_mask.update(self.extra_select_mask)
- if rhs.extra_select_mask is not None:
- extra_select_mask.update(rhs.extra_select_mask)
- if extra_select_mask:
- self.set_extra_mask(extra_select_mask)
- self.extra_tables += rhs.extra_tables
-
- # Ordering uses the 'rhs' ordering, unless it has none, in which case
- # the current ordering is used.
- self.order_by = rhs.order_by[:] if rhs.order_by else self.order_by
- self.extra_order_by = rhs.extra_order_by or self.extra_order_by
-
- def deferred_to_data(self, target, callback):
- """
- Converts the self.deferred_loading data structure to an alternate data
- structure, describing the field that *will* be loaded. This is used to
- compute the columns to select from the database and also by the
- QuerySet class to work out which fields are being initialised on each
- model. Models that have all their fields included aren't mentioned in
- the result, only those that have field restrictions in place.
-
- The "target" parameter is the instance that is populated (in place).
- The "callback" is a function that is called whenever a (model, field)
- pair need to be added to "target". It accepts three parameters:
- "target", and the model and list of fields being added for that model.
- """
- field_names, defer = self.deferred_loading
- if not field_names:
- return
- orig_opts = self.get_meta()
- seen = {}
- must_include = {orig_opts.concrete_model: set([orig_opts.pk])}
- for field_name in field_names:
- parts = field_name.split(LOOKUP_SEP)
- cur_model = self.model
- opts = orig_opts
- for name in parts[:-1]:
- old_model = cur_model
- source = opts.get_field_by_name(name)[0]
- if is_reverse_o2o(source):
- cur_model = source.model
- else:
- cur_model = source.rel.to
- opts = cur_model._meta
- # Even if we're "just passing through" this model, we must add
- # both the current model's pk and the related reference field
- # (if it's not a reverse relation) to the things we select.
- if not is_reverse_o2o(source):
- must_include[old_model].add(source)
- add_to_dict(must_include, cur_model, opts.pk)
- field, model, _, _ = opts.get_field_by_name(parts[-1])
- if model is None:
- model = cur_model
- if not is_reverse_o2o(field):
- add_to_dict(seen, model, field)
-
- if defer:
- # We need to load all fields for each model, except those that
- # appear in "seen" (for all models that appear in "seen"). The only
- # slight complexity here is handling fields that exist on parent
- # models.
- workset = {}
- for model, values in six.iteritems(seen):
- for field, m in model._meta.get_fields_with_model():
- if field in values:
- continue
- add_to_dict(workset, m or model, field)
- for model, values in six.iteritems(must_include):
- # If we haven't included a model in workset, we don't add the
- # corresponding must_include fields for that model, since an
- # empty set means "include all fields". That's why there's no
- # "else" branch here.
- if model in workset:
- workset[model].update(values)
- for model, values in six.iteritems(workset):
- callback(target, model, values)
- else:
- for model, values in six.iteritems(must_include):
- if model in seen:
- seen[model].update(values)
- else:
- # As we've passed through this model, but not explicitly
- # included any fields, we have to make sure it's mentioned
- # so that only the "must include" fields are pulled in.
- seen[model] = values
- # Now ensure that every model in the inheritance chain is mentioned
- # in the parent list. Again, it must be mentioned to ensure that
- # only "must include" fields are pulled in.
- for model in orig_opts.get_parent_list():
- if model not in seen:
- seen[model] = set()
- for model, values in six.iteritems(seen):
- callback(target, model, values)
-
-
- def deferred_to_columns_cb(self, target, model, fields):
- """
- Callback used by deferred_to_columns(). The "target" parameter should
- be a set instance.
- """
- table = model._meta.db_table
- if table not in target:
- target[table] = set()
- for field in fields:
- target[table].add(field.column)
-
-
- def table_alias(self, table_name, create=False):
- """
- Returns a table alias for the given table_name and whether this is a
- new alias or not.
-
- If 'create' is true, a new alias is always created. Otherwise, the
- most recently created alias for the table (if one exists) is reused.
- """
- current = self.table_map.get(table_name)
- if not create and current:
- alias = current[0]
- self.alias_refcount[alias] += 1
- return alias, False
-
- # Create a new alias for this table.
- if current:
- alias = '%s%d' % (self.alias_prefix, len(self.alias_map) + 1)
- current.append(alias)
- else:
- # The first occurence of a table uses the table name directly.
- alias = table_name
- self.table_map[alias] = [alias]
- self.alias_refcount[alias] = 1
- self.tables.append(alias)
- return alias, True
-
- def ref_alias(self, alias):
- """ Increases the reference count for this alias. """
- self.alias_refcount[alias] += 1
-
- def unref_alias(self, alias, amount=1):
- """ Decreases the reference count for this alias. """
- self.alias_refcount[alias] -= amount
-
- def promote_joins(self, aliases, unconditional=False):
- """
- Promotes recursively the join type of given aliases and its children to
- an outer join. If 'unconditional' is False, the join is only promoted if
- it is nullable or the parent join is an outer join.
-
- Note about join promotion: When promoting any alias, we make sure all
- joins which start from that alias are promoted, too. When adding a join
- in join(), we make sure any join added to already existing LOUTER join
- is generated as LOUTER. This ensures we don't ever have broken join
- chains which contain first a LOUTER join, then an INNER JOIN, that is
- this kind of join should never be generated: a LOUTER b INNER c. The
- reason for avoiding this type of join chain is that the INNER after
- the LOUTER will effectively remove any effect the LOUTER had.
- """
- aliases = list(aliases)
- while aliases:
- alias = aliases.pop(0)
- if self.alias_map[alias].join_cols[0][1] is None:
- # This is the base table (first FROM entry) - this table
- # isn't really joined at all in the query, so we should not
- # alter its join type.
- continue
- parent_alias = self.alias_map[alias].lhs_alias
- parent_louter = (parent_alias
- and self.alias_map[parent_alias].join_type == self.LOUTER)
- already_louter = self.alias_map[alias].join_type == self.LOUTER
- if ((unconditional or self.alias_map[alias].nullable
- or parent_louter) and not already_louter):
- data = self.alias_map[alias]._replace(join_type=self.LOUTER)
- self.alias_map[alias] = data
- # Join type of 'alias' changed, so re-examine all aliases that
- # refer to this one.
- aliases.extend(
- join for join in self.alias_map.keys()
- if (self.alias_map[join].lhs_alias == alias
- and join not in aliases))
-
- def reset_refcounts(self, to_counts):
- """
- This method will reset reference counts for aliases so that they match
- the value passed in :param to_counts:.
- """
- for alias, cur_refcount in self.alias_refcount.copy().items():
- unref_amount = cur_refcount - to_counts.get(alias, 0)
- self.unref_alias(alias, unref_amount)
-
- def promote_disjunction(self, aliases_before, alias_usage_counts,
- num_childs):
- """
- This method is to be used for promoting joins in ORed filters.
-
- The principle for promotion is: any alias which is used (it is in
- alias_usage_counts), is not used by every child of the ORed filter,
- and isn't pre-existing needs to be promoted to LOUTER join.
- """
- for alias, use_count in alias_usage_counts.items():
- if use_count < num_childs and alias not in aliases_before:
- self.promote_joins([alias])
-
- def change_aliases(self, change_map):
- """
- Changes the aliases in change_map (which maps old-alias -> new-alias),
- relabelling any references to them in select columns and the where
- clause.
- """
- assert set(change_map.keys()).intersection(set(change_map.values())) == set()
-
- def relabel_column(col):
- if isinstance(col, (list, tuple)):
- old_alias = col[0]
- return (change_map.get(old_alias, old_alias), col[1])
- else:
- return col.relabeled_clone(change_map)
- # 1. Update references in "select" (normal columns plus aliases),
- # "group by", "where" and "having".
- self.where.relabel_aliases(change_map)
- self.having.relabel_aliases(change_map)
- if self.group_by:
- self.group_by = [relabel_column(col) for col in self.group_by]
- self.select = [SelectInfo(relabel_column(s.col), s.field)
- for s in self.select]
- self.aggregates = SortedDict(
- (key, relabel_column(col)) for key, col in self.aggregates.items())
-
- # 2. Rename the alias in the internal table/alias datastructures.
- for ident, aliases in self.join_map.items():
- del self.join_map[ident]
- aliases = tuple([change_map.get(a, a) for a in aliases])
- ident = (change_map.get(ident[0], ident[0]),) + ident[1:]
- self.join_map[ident] = aliases
- for old_alias, new_alias in six.iteritems(change_map):
- alias_data = self.alias_map[old_alias]
- alias_data = alias_data._replace(rhs_alias=new_alias)
- self.alias_refcount[new_alias] = self.alias_refcount[old_alias]
- del self.alias_refcount[old_alias]
- self.alias_map[new_alias] = alias_data
- del self.alias_map[old_alias]
-
- table_aliases = self.table_map[alias_data.table_name]
- for pos, alias in enumerate(table_aliases):
- if alias == old_alias:
- table_aliases[pos] = new_alias
- break
- for pos, alias in enumerate(self.tables):
- if alias == old_alias:
- self.tables[pos] = new_alias
- break
- for key, alias in self.included_inherited_models.items():
- if alias in change_map:
- self.included_inherited_models[key] = change_map[alias]
-
- # 3. Update any joins that refer to the old alias.
- for alias, data in six.iteritems(self.alias_map):
- lhs = data.lhs_alias
- if lhs in change_map:
- data = data._replace(lhs_alias=change_map[lhs])
- self.alias_map[alias] = data
-
- def bump_prefix(self, exceptions=()):
- """
- Changes the alias prefix to the next letter in the alphabet and
- relabels all the aliases. Even tables that previously had no alias will
- get an alias after this call (it's mostly used for nested queries and
- the outer query will already be using the non-aliased table name).
-
- Subclasses who create their own prefix should override this method to
- produce a similar result (a new prefix and relabelled aliases).
-
- The 'exceptions' parameter is a container that holds alias names which
- should not be changed.
- """
- current = ord(self.alias_prefix)
- assert current < ord('Z')
- prefix = chr(current + 1)
- self.alias_prefix = prefix
- change_map = SortedDict()
- for pos, alias in enumerate(self.tables):
- if alias in exceptions:
- continue
- new_alias = '%s%d' % (prefix, pos)
- change_map[alias] = new_alias
- self.tables[pos] = new_alias
- self.change_aliases(change_map)
-
- def get_initial_alias(self):
- """
- Returns the first alias for this query, after increasing its reference
- count.
- """
- if self.tables:
- alias = self.tables[0]
- self.ref_alias(alias)
- else:
- alias = self.join((None, self.get_meta().db_table, None))
- return alias
-
- def count_active_tables(self):
- """
- Returns the number of tables in this query with a non-zero reference
- count. Note that after execution, the reference counts are zeroed, so
- tables added in compiler will not be seen by this method.
- """
- return len([1 for count in self.alias_refcount.values() if count])
-
- def join(self, connection, reuse=None, outer_if_first=False,
- nullable=False, join_field=None):
- """
- Returns an alias for the join in 'connection', either reusing an
- existing alias for that join or creating a new one. 'connection' is a
- tuple (lhs, table, join_cols) where 'lhs' is either an existing
- table alias or a table name. 'join_cols' is a tuple of tuples containing
- columns to join on ((l_id1, r_id1), (l_id2, r_id2)). The join corresponds
- to the SQL equivalent of::
-
- lhs.l_id1 = table.r_id1 AND lhs.l_id2 = table.r_id2
-
- The 'reuse' parameter can be either None which means all joins
- (matching the connection) are reusable, or it can be a set containing
- the aliases that can be reused.
-
- If 'outer_if_first' is True and a new join is created, it will have the
- LOUTER join type.
-
- A join is always created as LOUTER if the lhs alias is LOUTER to make
- sure we do not generate chains like t1 LOUTER t2 INNER t3.
-
- If 'nullable' is True, the join can potentially involve NULL values and
- is a candidate for promotion (to "left outer") when combining querysets.
-
- The 'join_field' is the field we are joining along (if any).
- """
- lhs, table, join_cols = connection
- assert lhs is None or join_field is not None
- existing = self.join_map.get(connection, ())
- if reuse is None:
- reuse = existing
- else:
- reuse = [a for a in existing if a in reuse]
- for alias in reuse:
- if join_field and self.alias_map[alias].join_field != join_field:
- # The join_map doesn't contain join_field (mainly because
- # fields in Query structs are problematic in pickling), so
- # check that the existing join is created using the same
- # join_field used for the under work join.
- continue
- self.ref_alias(alias)
- return alias
-
- # No reuse is possible, so we need a new alias.
- alias, _ = self.table_alias(table, True)
- if not lhs:
- # Not all tables need to be joined to anything. No join type
- # means the later columns are ignored.
- join_type = None
- elif outer_if_first or self.alias_map[lhs].join_type == self.LOUTER:
- # We need to use LOUTER join if asked by outer_if_first or if the
- # LHS table is left-joined in the query.
- join_type = self.LOUTER
- else:
- join_type = self.INNER
- join = JoinInfo(table, alias, join_type, lhs, join_cols or ((None, None),), nullable,
- join_field)
- self.alias_map[alias] = join
- if connection in self.join_map:
- self.join_map[connection] += (alias,)
- else:
- self.join_map[connection] = (alias,)
- return alias
-
- def setup_inherited_models(self):
- """
- If the model that is the basis for this QuerySet inherits other models,
- we need to ensure that those other models have their tables included in
- the query.
-
- We do this as a separate step so that subclasses know which
- tables are going to be active in the query, without needing to compute
- all the select columns (this method is called from pre_sql_setup(),
- whereas column determination is a later part, and side-effect, of
- as_sql()).
- """
- opts = self.get_meta()
- root_alias = self.tables[0]
- seen = {None: root_alias}
-
- for field, model in opts.get_fields_with_model():
- if model not in seen:
- self.join_parent_model(opts, model, root_alias, seen)
- self.included_inherited_models = seen
-
- def join_parent_model(self, opts, model, alias, seen):
- """
- Makes sure the given 'model' is joined in the query. If 'model' isn't
- a parent of 'opts' or if it is None this method is a no-op.
-
- The 'alias' is the root alias for starting the join, 'seen' is a dict
- of model -> alias of existing joins. It must also contain a mapping
- of None -> some alias. This will be returned in the no-op case.
- """
- if model in seen:
- return seen[model]
- chain = opts.get_base_chain(model)
- if chain is None:
- return alias
- curr_opts = opts
- for int_model in chain:
- if int_model in seen:
- return seen[int_model]
- # Proxy model have elements in base chain
- # with no parents, assign the new options
- # object and skip to the next base in that
- # case
- if not curr_opts.parents[int_model]:
- curr_opts = int_model._meta
- continue
- link_field = curr_opts.get_ancestor_link(int_model)
- _, _, _, joins, _ = self.setup_joins(
- [link_field.name], curr_opts, alias)
- curr_opts = int_model._meta
- alias = seen[int_model] = joins[-1]
- return alias or seen[None]
-
- def remove_inherited_models(self):
- """
- Undoes the effects of setup_inherited_models(). Should be called
- whenever select columns (self.select) are set explicitly.
- """
- for key, alias in self.included_inherited_models.items():
- if key:
- self.unref_alias(alias)
- self.included_inherited_models = {}
-
-
- def add_aggregate(self, aggregate, model, alias, is_summary):
- """
- Adds a single aggregate expression to the Query
- """
- opts = model._meta
- field_list = aggregate.lookup.split(LOOKUP_SEP)
- if len(field_list) == 1 and aggregate.lookup in self.aggregates:
- # Aggregate is over an annotation
- field_name = field_list[0]
- col = field_name
- source = self.aggregates[field_name]
- if not is_summary:
- raise FieldError("Cannot compute %s('%s'): '%s' is an aggregate" % (
- aggregate.name, field_name, field_name))
- elif ((len(field_list) > 1) or
- (field_list[0] not in [i.name for i in opts.fields]) or
- self.group_by is None or
- not is_summary):
- # If:
- # - the field descriptor has more than one part (foo__bar), or
- # - the field descriptor is referencing an m2m/m2o field, or
- # - this is a reference to a model field (possibly inherited), or
- # - this is an annotation over a model field
- # then we need to explore the joins that are required.
-
- field, sources, opts, join_list, path = self.setup_joins(
- field_list, opts, self.get_initial_alias())
-
- # Process the join chain to see if it can be trimmed
- targets, _, join_list = self.trim_joins(sources, join_list, path)
-
- # If the aggregate references a model or field that requires a join,
- # those joins must be LEFT OUTER - empty join rows must be returned
- # in order for zeros to be returned for those aggregates.
- self.promote_joins(join_list, True)
-
- col = targets[0].column
- source = sources[0]
- col = (join_list[-1], col)
- else:
- # The simplest cases. No joins required -
- # just reference the provided column alias.
- field_name = field_list[0]
- source = opts.get_field(field_name)
- col = field_name
-
- # Add the aggregate to the query
- aggregate.add_to_query(self, alias, col=col, source=source, is_summary=is_summary)
-
- def build_filter(self, filter_expr, branch_negated=False, current_negated=False,
- can_reuse=None):
- """
- Builds a WhereNode for a single filter clause, but doesn't add it
- to this Query. Query.add_q() will then add this filter to the where
- or having Node.
-
- The 'branch_negated' tells us if the current branch contains any
- negations. This will be used to determine if subqueries are needed.
-
- The 'current_negated' is used to determine if the current filter is
- negated or not and this will be used to determine if IS NULL filtering
- is needed.
-
- The difference between current_netageted and branch_negated is that
- branch_negated is set on first negation, but current_negated is
- flipped for each negation.
-
- Note that add_filter will not do any negating itself, that is done
- upper in the code by add_q().
-
- The 'can_reuse' is a set of reusable joins for multijoins.
-
- The method will create a filter clause that can be added to the current
- query. However, if the filter isn't added to the query then the caller
- is responsible for unreffing the joins used.
- """
- arg, value = filter_expr
- parts = arg.split(LOOKUP_SEP)
- if not parts:
- raise FieldError("Cannot parse keyword query %r" % arg)
-
- # Work out the lookup type and remove it from the end of 'parts',
- # if necessary.
- lookup_type = 'exact' # Default lookup type
- num_parts = len(parts)
- if (len(parts) > 1 and parts[-1] in self.query_terms
- and arg not in self.aggregates):
- # Traverse the lookup query to distinguish related fields from
- # lookup types.
- lookup_model = self.model
- for counter, field_name in enumerate(parts):
- try:
- lookup_field = lookup_model._meta.get_field(field_name)
- except FieldDoesNotExist:
- # Not a field. Bail out.
- lookup_type = parts.pop()
- break
- # Unless we're at the end of the list of lookups, let's attempt
- # to continue traversing relations.
- if (counter + 1) < num_parts:
- try:
- lookup_model = lookup_field.rel.to
- except AttributeError:
- # Not a related field. Bail out.
- lookup_type = parts.pop()
- break
-
- clause = self.where_class()
- # Interpret '__exact=None' as the sql 'is NULL'; otherwise, reject all
- # uses of None as a query value.
- if value is None:
- if lookup_type != 'exact':
- raise ValueError("Cannot use None as a query value")
- lookup_type = 'isnull'
- value = True
- elif callable(value):
- value = value()
- elif isinstance(value, ExpressionNode):
- # If value is a query expression, evaluate it
- value = SQLEvaluator(value, self, reuse=can_reuse)
- # For Oracle '' is equivalent to null. The check needs to be done
- # at this stage because join promotion can't be done at compiler
- # stage. Using DEFAULT_DB_ALIAS isn't nice, but it is the best we
- # can do here. Similar thing is done in is_nullable(), too.
- if (connections[DEFAULT_DB_ALIAS].features.interprets_empty_strings_as_nulls and
- lookup_type == 'exact' and value == ''):
- value = True
- lookup_type = 'isnull'
-
- for alias, aggregate in self.aggregates.items():
- if alias in (parts[0], LOOKUP_SEP.join(parts)):
- clause.add((aggregate, lookup_type, value), AND)
- return clause
-
- opts = self.get_meta()
- alias = self.get_initial_alias()
- allow_many = not branch_negated
-
- try:
- field, sources, opts, join_list, path = self.setup_joins(
- parts, opts, alias, can_reuse, allow_many,
- allow_explicit_fk=True)
- if can_reuse is not None:
- can_reuse.update(join_list)
- except MultiJoin as e:
- return self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]),
- can_reuse, e.names_with_path)
-
- if (lookup_type == 'isnull' and value is True and not current_negated and
- len(join_list) > 1):
- # If the comparison is against NULL, we may need to use some left
- # outer joins when creating the join chain. This is only done when
- # needed, as it's less efficient at the database level.
- self.promote_joins(join_list)
-
- # Process the join list to see if we can remove any inner joins from
- # the far end (fewer tables in a query is better). Note that join
- # promotion must happen before join trimming to have the join type
- # information available when reusing joins.
- targets, alias, join_list = self.trim_joins(sources, join_list, path)
-
- if hasattr(field, 'get_lookup_constraint'):
- constraint = field.get_lookup_constraint(self.where_class, alias, targets, sources,
- lookup_type, value)
- else:
- constraint = (Constraint(alias, targets[0].column, field), lookup_type, value)
- clause.add(constraint, AND)
- if current_negated and (lookup_type != 'isnull' or value is False):
- self.promote_joins(join_list)
- if (lookup_type != 'isnull' and (
- self.is_nullable(targets[0]) or
- self.alias_map[join_list[-1]].join_type == self.LOUTER)):
- # The condition added here will be SQL like this:
- # NOT (col IS NOT NULL), where the first NOT is added in
- # upper layers of code. The reason for addition is that if col
- # is null, then col != someval will result in SQL "unknown"
- # which isn't the same as in Python. The Python None handling
- # is wanted, and it can be gotten by
- # (col IS NULL OR col != someval)
- # <=>
- # NOT (col IS NOT NULL AND col = someval).
- clause.add((Constraint(alias, targets[0].column, None), 'isnull', False), AND)
- return clause
-
- def add_filter(self, filter_clause):
- self.where.add(self.build_filter(filter_clause), 'AND')
-
- def need_having(self, obj):
- """
- Returns whether or not all elements of this q_object need to be put
- together in the HAVING clause.
- """
- if not isinstance(obj, Node):
- return (refs_aggregate(obj[0].split(LOOKUP_SEP), self.aggregates)
- or (hasattr(obj[1], 'contains_aggregate')
- and obj[1].contains_aggregate(self.aggregates)))
- return any(self.need_having(c) for c in obj.children)
-
- def split_having_parts(self, q_object, negated=False):
- """
- Returns a list of q_objects which need to go into the having clause
- instead of the where clause. Removes the splitted out nodes from the
- given q_object. Note that the q_object is altered, so cloning it is
- needed.
- """
- having_parts = []
- for c in q_object.children[:]:
- # When constucting the having nodes we need to take care to
- # preserve the negation status from the upper parts of the tree
- if isinstance(c, Node):
- # For each negated child, flip the in_negated flag.
- in_negated = c.negated ^ negated
- if c.connector == OR and self.need_having(c):
- # A subtree starting from OR clause must go into having in
- # whole if any part of that tree references an aggregate.
- q_object.children.remove(c)
- having_parts.append(c)
- c.negated = in_negated
- else:
- having_parts.extend(
- self.split_having_parts(c, in_negated)[1])
- elif self.need_having(c):
- q_object.children.remove(c)
- new_q = self.where_class(children=[c], negated=negated)
- having_parts.append(new_q)
- return q_object, having_parts
-
- def add_q(self, q_object):
- """
- A preprocessor for the internal _add_q(). Responsible for
- splitting the given q_object into where and having parts and
- setting up some internal variables.
- """
- if not self.need_having(q_object):
- where_part, having_parts = q_object, []
- else:
- where_part, having_parts = self.split_having_parts(
- q_object.clone(), q_object.negated)
- used_aliases = self.used_aliases
- clause = self._add_q(where_part, used_aliases)
- self.where.add(clause, AND)
- for hp in having_parts:
- clause = self._add_q(hp, used_aliases)
- self.having.add(clause, AND)
- if self.filter_is_sticky:
- self.used_aliases = used_aliases
-
- def _add_q(self, q_object, used_aliases, branch_negated=False,
- current_negated=False):
- """
- Adds a Q-object to the current filter.
- """
- connector = q_object.connector
- current_negated = current_negated ^ q_object.negated
- branch_negated = branch_negated or q_object.negated
- target_clause = self.where_class(connector=connector,
- negated=q_object.negated)
- # Treat case NOT (a AND b) like case ((NOT a) OR (NOT b)) for join
- # promotion. See ticket #21748.
- effective_connector = connector
- if current_negated:
- effective_connector = OR if effective_connector == AND else AND
- if effective_connector == OR:
- alias_usage_counts = dict()
- aliases_before = set(self.tables)
- for child in q_object.children:
- if effective_connector == OR:
- refcounts_before = self.alias_refcount.copy()
- if isinstance(child, Node):
- child_clause = self._add_q(
- child, used_aliases, branch_negated,
- current_negated)
- else:
- child_clause = self.build_filter(
- child, can_reuse=used_aliases, branch_negated=branch_negated,
- current_negated=current_negated)
- target_clause.add(child_clause, connector)
- if effective_connector == OR:
- used = alias_diff(refcounts_before, self.alias_refcount)
- for alias in used:
- alias_usage_counts[alias] = alias_usage_counts.get(alias, 0) + 1
- if effective_connector == OR:
- self.promote_disjunction(aliases_before, alias_usage_counts,
- len(q_object.children))
- return target_clause
-
- def names_to_path(self, names, opts, allow_many, allow_explicit_fk):
- """
- Walks the names path and turns them PathInfo tuples. Note that a
- single name in 'names' can generate multiple PathInfos (m2m for
- example).
-
- 'names' is the path of names to travle, 'opts' is the model Options we
- start the name resolving from, 'allow_many' and 'allow_explicit_fk'
- are as for setup_joins().
-
- Returns a list of PathInfo tuples. In addition returns the final field
- (the last used join field), and target (which is a field guaranteed to
- contain the same value as the final field).
- """
- path, names_with_path = [], []
- for pos, name in enumerate(names):
- cur_names_with_path = (name, [])
- if name == 'pk':
- name = opts.pk.name
- try:
- field, model, direct, m2m = opts.get_field_by_name(name)
- except FieldDoesNotExist:
- for f in opts.fields:
- if allow_explicit_fk and name == f.attname:
- # XXX: A hack to allow foo_id to work in values() for
- # backwards compatibility purposes. If we dropped that
- # feature, this could be removed.
- field, model, direct, m2m = opts.get_field_by_name(f.name)
- break
- else:
- available = opts.get_all_field_names() + list(self.aggregate_select)
- raise FieldError("Cannot resolve keyword %r into field. "
- "Choices are: %s" % (name, ", ".join(available)))
- # Check if we need any joins for concrete inheritance cases (the
- # field lives in parent, but we are currently in one of its
- # children)
- if model:
- # The field lives on a base class of the current model.
- # Skip the chain of proxy to the concrete proxied model
- proxied_model = opts.concrete_model
-
- for int_model in opts.get_base_chain(model):
- if int_model is proxied_model:
- opts = int_model._meta
- else:
- final_field = opts.parents[int_model]
- targets = (final_field.rel.get_related_field(),)
- opts = int_model._meta
- path.append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
- cur_names_with_path[1].append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
- if hasattr(field, 'get_path_info'):
- pathinfos = field.get_path_info()
- if not allow_many:
- for inner_pos, p in enumerate(pathinfos):
- if p.m2m:
- cur_names_with_path[1].extend(pathinfos[0:inner_pos + 1])
- names_with_path.append(cur_names_with_path)
- raise MultiJoin(pos + 1, names_with_path)
- last = pathinfos[-1]
- path.extend(pathinfos)
- final_field = last.join_field
- opts = last.to_opts
- targets = last.target_fields
- cur_names_with_path[1].extend(pathinfos)
- names_with_path.append(cur_names_with_path)
- else:
- # Local non-relational field.
- final_field = field
- targets = (field,)
- break
-
- if pos != len(names) - 1:
- if pos == len(names) - 2:
- raise FieldError(
- "Join on field %r not permitted. Did you misspell %r for "
- "the lookup type?" % (name, names[pos + 1]))
- else:
- raise FieldError("Join on field %r not permitted." % name)
- return path, final_field, targets
-
- def setup_joins(self, names, opts, alias, can_reuse=None, allow_many=True,
- allow_explicit_fk=False, outer_if_first=False):
- """
- Compute the necessary table joins for the passage through the fields
- given in 'names'. 'opts' is the Options class for the current model
- (which gives the table we are starting from), 'alias' is the alias for
- the table to start the joining from.
-
- The 'can_reuse' defines the reverse foreign key joins we can reuse. It
- can be None in which case all joins are reusable or a set of aliases
- that can be reused. Note that non-reverse foreign keys are always
- reusable when using setup_joins().
-
- If 'allow_many' is False, then any reverse foreign key seen will
- generate a MultiJoin exception.
-
- The 'allow_explicit_fk' controls if field.attname is allowed in the
- lookups.
-
- Returns the final field involved in the joins, the target field (used
- for any 'where' constraint), the final 'opts' value, the joins and the
- field path travelled to generate the joins.
-
- The target field is the field containing the concrete value. Final
- field can be something different, for example foreign key pointing to
- that value. Final field is needed for example in some value
- conversions (convert 'obj' in fk__id=obj to pk val using the foreign
- key field for example).
- """
- joins = [alias]
- # First, generate the path for the names
- path, final_field, targets = self.names_to_path(
- names, opts, allow_many, allow_explicit_fk)
- # Then, add the path to the query's joins. Note that we can't trim
- # joins at this stage - we will need the information about join type
- # of the trimmed joins.
- for pos, join in enumerate(path):
- opts = join.to_opts
- if join.direct:
- nullable = self.is_nullable(join.join_field)
- else:
- nullable = True
- connection = alias, opts.db_table, join.join_field.get_joining_columns()
- reuse = can_reuse if join.m2m else None
- alias = self.join(
- connection, reuse=reuse, nullable=nullable, join_field=join.join_field,
- outer_if_first=outer_if_first)
- joins.append(alias)
- if hasattr(final_field, 'field'):
- final_field = final_field.field
- return final_field, targets, opts, joins, path
-
- def trim_joins(self, targets, joins, path):
- """
- The 'target' parameter is the final field being joined to, 'joins'
- is the full list of join aliases. The 'path' contain the PathInfos
- used to create the joins.
-
- Returns the final target field and table alias and the new active
- joins.
-
- We will always trim any direct join if we have the target column
- available already in the previous table. Reverse joins can't be
- trimmed as we don't know if there is anything on the other side of
- the join.
- """
- for pos, info in enumerate(reversed(path)):
- if len(joins) == 1 or not info.direct:
- break
- join_targets = set(t.column for t in info.join_field.foreign_related_fields)
- cur_targets = set(t.column for t in targets)
- if not cur_targets.issubset(join_targets):
- break
- targets = tuple(r[0] for r in info.join_field.related_fields if r[1].column in cur_targets)
- self.unref_alias(joins.pop())
- return targets, joins[-1], joins
-
- def split_exclude(self, filter_expr, prefix, can_reuse, names_with_path):
- """
- When doing an exclude against any kind of N-to-many relation, we need
- to use a subquery. This method constructs the nested query, given the
- original exclude filter (filter_expr) and the portion up to the first
- N-to-many relation field.
-
- As an example we could have original filter ~Q(child__name='foo').
- We would get here with filter_expr = child__name, prefix = child and
- can_reuse is a set of joins usable for filters in the original query.
-
- We will turn this into equivalent of:
- WHERE NOT (pk IN (SELECT parent_id FROM thetable
- WHERE name = 'foo' AND parent_id IS NOT NULL))
-
- It might be worth it to consider using WHERE NOT EXISTS as that has
- saner null handling, and is easier for the backend's optimizer to
- handle.
- """
- # Generate the inner query.
- query = Query(self.model)
- query.where.add(query.build_filter(filter_expr), AND)
- query.bump_prefix()
- query.clear_ordering(True)
- # Try to have as simple as possible subquery -> trim leading joins from
- # the subquery.
- trimmed_prefix, contains_louter = query.trim_start(names_with_path)
- query.remove_inherited_models()
-
- # Add extra check to make sure the selected field will not be null
- # since we are adding a IN <subquery> clause. This prevents the
- # database from tripping over IN (...,NULL,...) selects and returning
- # nothing
- if self.is_nullable(query.select[0].field):
- alias, col = query.select[0].col
- query.where.add((Constraint(alias, col, query.select[0].field), 'isnull', False), AND)
-
- condition = self.build_filter(
- ('%s__in' % trimmed_prefix, query),
- current_negated=True, branch_negated=True, can_reuse=can_reuse)
- if contains_louter:
- or_null_condition = self.build_filter(
- ('%s__isnull' % trimmed_prefix, True),
- current_negated=True, branch_negated=True, can_reuse=can_reuse)
- condition.add(or_null_condition, OR)
- # Note that the end result will be:
- # (outercol NOT IN innerq AND outercol IS NOT NULL) OR outercol IS NULL.
- # This might look crazy but due to how IN works, this seems to be
- # correct. If the IS NOT NULL check is removed then outercol NOT
- # IN will return UNKNOWN. If the IS NULL check is removed, then if
- # outercol IS NULL we will not match the row.
- return condition
-
- def set_empty(self):
- self.where = EmptyWhere()
- self.having = EmptyWhere()
-
- def is_empty(self):
- return isinstance(self.where, EmptyWhere) or isinstance(self.having, EmptyWhere)
-
- def set_limits(self, low=None, high=None):
- """
- Adjusts the limits on the rows retrieved. We use low/high to set these,
- as it makes it more Pythonic to read and write. When the SQL query is
- created, they are converted to the appropriate offset and limit values.
-
- Any limits passed in here are applied relative to the existing
- constraints. So low is added to the current low value and both will be
- clamped to any existing high value.
- """
- if high is not None:
- if self.high_mark is not None:
- self.high_mark = min(self.high_mark, self.low_mark + high)
- else:
- self.high_mark = self.low_mark + high
- if low is not None:
- if self.high_mark is not None:
- self.low_mark = min(self.high_mark, self.low_mark + low)
- else:
- self.low_mark = self.low_mark + low
-
- def clear_limits(self):
- """
- Clears any existing limits.
- """
- self.low_mark, self.high_mark = 0, None
-
- def can_filter(self):
- """
- Returns True if adding filters to this instance is still possible.
-
- Typically, this means no limits or offsets have been put on the results.
- """
- return not self.low_mark and self.high_mark is None
-
- def clear_select_clause(self):
- """
- Removes all fields from SELECT clause.
- """
- self.select = []
- self.default_cols = False
- self.select_related = False
- self.set_extra_mask(())
- self.set_aggregate_mask(())
-
- def clear_select_fields(self):
- """
- Clears the list of fields to select (but not extra_select columns).
- Some queryset types completely replace any existing list of select
- columns.
- """
- self.select = []
-
- def add_distinct_fields(self, *field_names):
- """
- Adds and resolves the given fields to the query's "distinct on" clause.
- """
- self.distinct_fields = field_names
- self.distinct = True
-
- def add_fields(self, field_names, allow_m2m=True):
- """
- Adds the given (model) fields to the select set. The field names are
- added in the order specified.
- """
- alias = self.get_initial_alias()
- opts = self.get_meta()
-
- try:
- for name in field_names:
- field, targets, u2, joins, path = self.setup_joins(
- name.split(LOOKUP_SEP), opts, alias, None, allow_m2m,
- allow_explicit_fk=True, outer_if_first=True)
-
- # Trim last join if possible
- targets, final_alias, remaining_joins = self.trim_joins(targets, joins[-2:], path)
- joins = joins[:-2] + remaining_joins
-
- self.promote_joins(joins[1:])
- for target in targets:
- self.select.append(SelectInfo((final_alias, target.column), target))
- except MultiJoin:
- raise FieldError("Invalid field name: '%s'" % name)
- except FieldError:
- if LOOKUP_SEP in name:
- # For lookups spanning over relationships, show the error
- # from the model on which the lookup failed.
- raise
- else:
- names = sorted(opts.get_all_field_names() + list(self.extra)
- + list(self.aggregate_select))
- raise FieldError("Cannot resolve keyword %r into field. "
- "Choices are: %s" % (name, ", ".join(names)))
- self.remove_inherited_models()
-
- def add_ordering(self, *ordering):
- """
- Adds items from the 'ordering' sequence to the query's "order by"
- clause. These items are either field names (not column names) --
- possibly with a direction prefix ('-' or '?') -- or ordinals,
- corresponding to column positions in the 'select' list.
-
- If 'ordering' is empty, all ordering is cleared from the query.
- """
- errors = []
- for item in ordering:
- if not ORDER_PATTERN.match(item):
- errors.append(item)
- if errors:
- raise FieldError('Invalid order_by arguments: %s' % errors)
- if ordering:
- self.order_by.extend(ordering)
- else:
- self.default_ordering = False
-
- def clear_ordering(self, force_empty):
- """
- Removes any ordering settings. If 'force_empty' is True, there will be
- no ordering in the resulting query (not even the model's default).
- """
- self.order_by = []
- self.extra_order_by = ()
- if force_empty:
- self.default_ordering = False
-
- def set_group_by(self):
- """
- Expands the GROUP BY clause required by the query.
-
- This will usually be the set of all non-aggregate fields in the
- return data. If the database backend supports grouping by the
- primary key, and the query would be equivalent, the optimization
- will be made automatically.
- """
- self.group_by = []
-
- for col, _ in self.select:
- self.group_by.append(col)
-
- def add_count_column(self):
- """
- Converts the query to do count(...) or count(distinct(pk)) in order to
- get its size.
- """
- if not self.distinct:
- if not self.select:
- count = self.aggregates_module.Count('*', is_summary=True)
- else:
- assert len(self.select) == 1, \
- "Cannot add count col with multiple cols in 'select': %r" % self.select
- count = self.aggregates_module.Count(self.select[0].col)
- else:
- opts = self.get_meta()
- if not self.select:
- count = self.aggregates_module.Count(
- (self.join((None, opts.db_table, None)), opts.pk.column),
- is_summary=True, distinct=True)
- else:
- # Because of SQL portability issues, multi-column, distinct
- # counts need a sub-query -- see get_count() for details.
- assert len(self.select) == 1, \
- "Cannot add count col with multiple cols in 'select'."
-
- count = self.aggregates_module.Count(self.select[0].col, distinct=True)
- # Distinct handling is done in Count(), so don't do it at this
- # level.
- self.distinct = False
-
- # Set only aggregate to be the count column.
- # Clear out the select cache to reflect the new unmasked aggregates.
- self.aggregates = {None: count}
- self.set_aggregate_mask(None)
- self.group_by = None
-
- def add_select_related(self, fields):
- """
- Sets up the select_related data structure so that we only select
- certain related models (as opposed to all models, when
- self.select_related=True).
- """
- field_dict = {}
- for field in fields:
- d = field_dict
- for part in field.split(LOOKUP_SEP):
- d = d.setdefault(part, {})
- self.select_related = field_dict
- self.related_select_cols = []
-
- def add_extra(self, select, select_params, where, params, tables, order_by):
- """
- Adds data to the various extra_* attributes for user-created additions
- to the query.
- """
- if select:
- # We need to pair any placeholder markers in the 'select'
- # dictionary with their parameters in 'select_params' so that
- # subsequent updates to the select dictionary also adjust the
- # parameters appropriately.
- select_pairs = SortedDict()
- if select_params:
- param_iter = iter(select_params)
- else:
- param_iter = iter([])
- for name, entry in select.items():
- entry = force_text(entry)
- entry_params = []
- pos = entry.find("%s")
- while pos != -1:
- entry_params.append(next(param_iter))
- pos = entry.find("%s", pos + 2)
- select_pairs[name] = (entry, entry_params)
- # This is order preserving, since self.extra_select is a SortedDict.
- self.extra.update(select_pairs)
- if where or params:
- self.where.add(ExtraWhere(where, params), AND)
- if tables:
- self.extra_tables += tuple(tables)
- if order_by:
- self.extra_order_by = order_by
-
- def clear_deferred_loading(self):
- """
- Remove any fields from the deferred loading set.
- """
- self.deferred_loading = (set(), True)
-
- def add_deferred_loading(self, field_names):
- """
- Add the given list of model field names to the set of fields to
- exclude from loading from the database when automatic column selection
- is done. The new field names are added to any existing field names that
- are deferred (or removed from any existing field names that are marked
- as the only ones for immediate loading).
- """
- # Fields on related models are stored in the literal double-underscore
- # format, so that we can use a set datastructure. We do the foo__bar
- # splitting and handling when computing the SQL colum names (as part of
- # get_columns()).
- existing, defer = self.deferred_loading
- if defer:
- # Add to existing deferred names.
- self.deferred_loading = existing.union(field_names), True
- else:
- # Remove names from the set of any existing "immediate load" names.
- self.deferred_loading = existing.difference(field_names), False
-
- def add_immediate_loading(self, field_names):
- """
- Add the given list of model field names to the set of fields to
- retrieve when the SQL is executed ("immediate loading" fields). The
- field names replace any existing immediate loading field names. If
- there are field names already specified for deferred loading, those
- names are removed from the new field_names before storing the new names
- for immediate loading. (That is, immediate loading overrides any
- existing immediate values, but respects existing deferrals.)
- """
- existing, defer = self.deferred_loading
- field_names = set(field_names)
- if 'pk' in field_names:
- field_names.remove('pk')
- field_names.add(self.get_meta().pk.name)
-
- if defer:
- # Remove any existing deferred names from the current set before
- # setting the new names.
- self.deferred_loading = field_names.difference(existing), False
- else:
- # Replace any existing "immediate load" field names.
- self.deferred_loading = field_names, False
-
- def get_loaded_field_names(self):
- """
- If any fields are marked to be deferred, returns a dictionary mapping
- models to a set of names in those fields that will be loaded. If a
- model is not in the returned dictionary, none of it's fields are
- deferred.
-
- If no fields are marked for deferral, returns an empty dictionary.
- """
- # We cache this because we call this function multiple times
- # (compiler.fill_related_selections, query.iterator)
- try:
- return self._loaded_field_names_cache
- except AttributeError:
- collection = {}
- self.deferred_to_data(collection, self.get_loaded_field_names_cb)
- self._loaded_field_names_cache = collection
- return collection
-
- def get_loaded_field_names_cb(self, target, model, fields):
- """
- Callback used by get_deferred_field_names().
- """
- target[model] = set([f.name for f in fields])
-
- def set_aggregate_mask(self, names):
- "Set the mask of aggregates that will actually be returned by the SELECT"
- if names is None:
- self.aggregate_select_mask = None
- else:
- self.aggregate_select_mask = set(names)
- self._aggregate_select_cache = None
-
- def set_extra_mask(self, names):
- """
- Set the mask of extra select items that will be returned by SELECT,
- we don't actually remove them from the Query since they might be used
- later
- """
- if names is None:
- self.extra_select_mask = None
- else:
- self.extra_select_mask = set(names)
- self._extra_select_cache = None
-
- def _aggregate_select(self):
- """The SortedDict of aggregate columns that are not masked, and should
- be used in the SELECT clause.
-
- This result is cached for optimization purposes.
- """
- if self._aggregate_select_cache is not None:
- return self._aggregate_select_cache
- elif self.aggregate_select_mask is not None:
- self._aggregate_select_cache = SortedDict([
- (k,v) for k,v in self.aggregates.items()
- if k in self.aggregate_select_mask
- ])
- return self._aggregate_select_cache
- else:
- return self.aggregates
- aggregate_select = property(_aggregate_select)
-
- def _extra_select(self):
- if self._extra_select_cache is not None:
- return self._extra_select_cache
- elif self.extra_select_mask is not None:
- self._extra_select_cache = SortedDict([
- (k,v) for k,v in self.extra.items()
- if k in self.extra_select_mask
- ])
- return self._extra_select_cache
- else:
- return self.extra
- extra_select = property(_extra_select)
-
- def trim_start(self, names_with_path):
- """
- Trims joins from the start of the join path. The candidates for trim
- are the PathInfos in names_with_path structure that are m2m joins.
-
- Also sets the select column so the start matches the join.
-
- This method is meant to be used for generating the subquery joins &
- cols in split_exclude().
-
- Returns a lookup usable for doing outerq.filter(lookup=self). Returns
- also if the joins in the prefix contain a LEFT OUTER join.
- _"""
- all_paths = []
- for _, paths in names_with_path:
- all_paths.extend(paths)
- contains_louter = False
- for pos, path in enumerate(all_paths):
- if path.m2m:
- break
- if self.alias_map[self.tables[pos + 1]].join_type == self.LOUTER:
- contains_louter = True
- self.unref_alias(self.tables[pos])
- # The path.join_field is a Rel, lets get the other side's field
- join_field = path.join_field.field
- # Build the filter prefix.
- trimmed_prefix = []
- paths_in_prefix = pos
- for name, path in names_with_path:
- if paths_in_prefix - len(path) < 0:
- break
- trimmed_prefix.append(name)
- paths_in_prefix -= len(path)
- trimmed_prefix.append(
- join_field.foreign_related_fields[0].name)
- trimmed_prefix = LOOKUP_SEP.join(trimmed_prefix)
- # Lets still see if we can trim the first join from the inner query
- # (that is, self). We can't do this for LEFT JOINs because we would
- # miss those rows that have nothing on the outer side.
- if self.alias_map[self.tables[pos + 1]].join_type != self.LOUTER:
- select_fields = [r[0] for r in join_field.related_fields]
- select_alias = self.tables[pos + 1]
- self.unref_alias(self.tables[pos])
- extra_restriction = join_field.get_extra_restriction(
- self.where_class, None, self.tables[pos + 1])
- if extra_restriction:
- self.where.add(extra_restriction, AND)
- else:
- # TODO: It might be possible to trim more joins from the start of the
- # inner query if it happens to have a longer join chain containing the
- # values in select_fields. Lets punt this one for now.
- select_fields = [r[1] for r in join_field.related_fields]
- select_alias = self.tables[pos]
- self.select = [SelectInfo((select_alias, f.column), f) for f in select_fields]
- return trimmed_prefix, contains_louter
-
- def is_nullable(self, field):
- """
- A helper to check if the given field should be treated as nullable.
-
- Some backends treat '' as null and Django treats such fields as
- nullable for those backends. In such situations field.null can be
- False even if we should treat the field as nullable.
- """
- # We need to use DEFAULT_DB_ALIAS here, as QuerySet does not have
- # (nor should it have) knowledge of which connection is going to be
- # used. The proper fix would be to defer all decisions where
- # is_nullable() is needed to the compiler stage, but that is not easy
- # to do currently.
- if ((connections[DEFAULT_DB_ALIAS].features.interprets_empty_strings_as_nulls)
- and field.empty_strings_allowed):
- return True
- else:
- return field.null
-
-def get_order_dir(field, default='ASC'):
- """
- Returns the field name and direction for an order specification. For
- example, '-foo' is returned as ('foo', 'DESC').
-
- The 'default' param is used to indicate which way no prefix (or a '+'
- prefix) should sort. The '-' prefix always sorts the opposite way.
- """
- dirn = ORDER_DIR[default]
- if field[0] == '-':
- return field[1:], dirn[1]
- return field, dirn[0]
-
-
-def add_to_dict(data, key, value):
- """
- A helper function to add "value" to the set of values for "key", whether or
- not "key" already exists.
- """
- if key in data:
- data[key].add(value)
- else:
- data[key] = set([value])
-
-def is_reverse_o2o(field):
- """
- A little helper to check if the given field is reverse-o2o. The field is
- expected to be some sort of relation field or related object.
- """
- return not hasattr(field, 'rel') and field.field.unique
-
-def alias_diff(refcounts_before, refcounts_after):
- """
- Given the before and after copies of refcounts works out which aliases
- have been added to the after copy.
- """
- # Use -1 as default value so that any join that is created, then trimmed
- # is seen as added.
- return set(t for t in refcounts_after
- if refcounts_after[t] > refcounts_before.get(t, -1))
diff --git a/lib/python2.7/site-packages/django/db/models/sql/subqueries.py b/lib/python2.7/site-packages/django/db/models/sql/subqueries.py
deleted file mode 100644
index 6dc0005..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/subqueries.py
+++ /dev/null
@@ -1,297 +0,0 @@
-"""
-Query subclasses which provide extra functionality beyond simple data retrieval.
-"""
-
-from django.conf import settings
-from django.core.exceptions import FieldError
-from django.db import connections
-from django.db.models.constants import LOOKUP_SEP
-from django.db.models.fields import DateField, DateTimeField, FieldDoesNotExist
-from django.db.models.sql.constants import *
-from django.db.models.sql.datastructures import Date, DateTime
-from django.db.models.sql.query import Query
-from django.db.models.sql.where import AND, Constraint
-from django.utils.functional import Promise
-from django.utils.encoding import force_text
-from django.utils import six
-from django.utils import timezone
-
-
-__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
- 'DateTimeQuery', 'AggregateQuery']
-
-class DeleteQuery(Query):
- """
- Delete queries are done through this class, since they are more constrained
- than general queries.
- """
-
- compiler = 'SQLDeleteCompiler'
-
- def do_query(self, table, where, using):
- self.tables = [table]
- self.where = where
- self.get_compiler(using).execute_sql(None)
-
- def delete_batch(self, pk_list, using, field=None):
- """
- Set up and execute delete queries for all the objects in pk_list.
-
- More than one physical query may be executed if there are a
- lot of values in pk_list.
- """
- if not field:
- field = self.get_meta().pk
- for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
- where = self.where_class()
- where.add((Constraint(None, field.column, field), 'in',
- pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]), AND)
- self.do_query(self.get_meta().db_table, where, using=using)
-
- def delete_qs(self, query, using):
- """
- Delete the queryset in one SQL query (if possible). For simple queries
- this is done by copying the query.query.where to self.query, for
- complex queries by using subquery.
- """
- innerq = query.query
- # Make sure the inner query has at least one table in use.
- innerq.get_initial_alias()
- # The same for our new query.
- self.get_initial_alias()
- innerq_used_tables = [t for t in innerq.tables
- if innerq.alias_refcount[t]]
- if ((not innerq_used_tables or innerq_used_tables == self.tables)
- and not len(innerq.having)):
- # There is only the base table in use in the query, and there are
- # no aggregate filtering going on.
- self.where = innerq.where
- else:
- pk = query.model._meta.pk
- if not connections[using].features.update_can_self_select:
- # We can't do the delete using subquery.
- values = list(query.values_list('pk', flat=True))
- if not values:
- return
- self.delete_batch(values, using)
- return
- else:
- innerq.clear_select_clause()
- innerq.select = [SelectInfo((self.get_initial_alias(), pk.column), None)]
- values = innerq
- where = self.where_class()
- where.add((Constraint(None, pk.column, pk), 'in', values), AND)
- self.where = where
- self.get_compiler(using).execute_sql(None)
-
-
-class UpdateQuery(Query):
- """
- Represents an "update" SQL query.
- """
-
- compiler = 'SQLUpdateCompiler'
-
- def __init__(self, *args, **kwargs):
- super(UpdateQuery, self).__init__(*args, **kwargs)
- self._setup_query()
-
- def _setup_query(self):
- """
- Runs on initialization and after cloning. Any attributes that would
- normally be set in __init__ should go in here, instead, so that they
- are also set up after a clone() call.
- """
- self.values = []
- self.related_ids = None
- if not hasattr(self, 'related_updates'):
- self.related_updates = {}
-
- def clone(self, klass=None, **kwargs):
- return super(UpdateQuery, self).clone(klass,
- related_updates=self.related_updates.copy(), **kwargs)
-
- def update_batch(self, pk_list, values, using):
- pk_field = self.get_meta().pk
- self.add_update_values(values)
- for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
- self.where = self.where_class()
- self.where.add((Constraint(None, pk_field.column, pk_field), 'in',
- pk_list[offset:offset + GET_ITERATOR_CHUNK_SIZE]),
- AND)
- self.get_compiler(using).execute_sql(None)
-
- def add_update_values(self, values):
- """
- Convert a dictionary of field name to value mappings into an update
- query. This is the entry point for the public update() method on
- querysets.
- """
- values_seq = []
- for name, val in six.iteritems(values):
- field, model, direct, m2m = self.get_meta().get_field_by_name(name)
- if not direct or m2m:
- raise FieldError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)
- if model:
- self.add_related_update(model, field, val)
- continue
- values_seq.append((field, model, val))
- return self.add_update_fields(values_seq)
-
- def add_update_fields(self, values_seq):
- """
- Turn a sequence of (field, model, value) triples into an update query.
- Used by add_update_values() as well as the "fast" update path when
- saving models.
- """
- # Check that no Promise object passes to the query. Refs #10498.
- values_seq = [(value[0], value[1], force_text(value[2]))
- if isinstance(value[2], Promise) else value
- for value in values_seq]
- self.values.extend(values_seq)
-
- def add_related_update(self, model, field, value):
- """
- Adds (name, value) to an update query for an ancestor model.
-
- Updates are coalesced so that we only run one update query per ancestor.
- """
- try:
- self.related_updates[model].append((field, None, value))
- except KeyError:
- self.related_updates[model] = [(field, None, value)]
-
- def get_related_updates(self):
- """
- Returns a list of query objects: one for each update required to an
- ancestor model. Each query will have the same filtering conditions as
- the current query but will only update a single table.
- """
- if not self.related_updates:
- return []
- result = []
- for model, values in six.iteritems(self.related_updates):
- query = UpdateQuery(model)
- query.values = values
- if self.related_ids is not None:
- query.add_filter(('pk__in', self.related_ids))
- result.append(query)
- return result
-
-class InsertQuery(Query):
- compiler = 'SQLInsertCompiler'
-
- def __init__(self, *args, **kwargs):
- super(InsertQuery, self).__init__(*args, **kwargs)
- self.fields = []
- self.objs = []
-
- def clone(self, klass=None, **kwargs):
- extras = {
- 'fields': self.fields[:],
- 'objs': self.objs[:],
- 'raw': self.raw,
- }
- extras.update(kwargs)
- return super(InsertQuery, self).clone(klass, **extras)
-
- def insert_values(self, fields, objs, raw=False):
- """
- Set up the insert query from the 'insert_values' dictionary. The
- dictionary gives the model field names and their target values.
-
- If 'raw_values' is True, the values in the 'insert_values' dictionary
- are inserted directly into the query, rather than passed as SQL
- parameters. This provides a way to insert NULL and DEFAULT keywords
- into the query, for example.
- """
- self.fields = fields
- # Check that no Promise object reaches the DB. Refs #10498.
- for field in fields:
- for obj in objs:
- value = getattr(obj, field.attname)
- if isinstance(value, Promise):
- setattr(obj, field.attname, force_text(value))
- self.objs = objs
- self.raw = raw
-
-class DateQuery(Query):
- """
- A DateQuery is a normal query, except that it specifically selects a single
- date field. This requires some special handling when converting the results
- back to Python objects, so we put it in a separate class.
- """
-
- compiler = 'SQLDateCompiler'
-
- def add_select(self, field_name, lookup_type, order='ASC'):
- """
- Converts the query into an extraction query.
- """
- try:
- result = self.setup_joins(
- field_name.split(LOOKUP_SEP),
- self.get_meta(),
- self.get_initial_alias(),
- )
- except FieldError:
- raise FieldDoesNotExist("%s has no field named '%s'" % (
- self.get_meta().object_name, field_name
- ))
- field = result[0]
- self._check_field(field) # overridden in DateTimeQuery
- alias = result[3][-1]
- select = self._get_select((alias, field.column), lookup_type)
- self.clear_select_clause()
- self.select = [SelectInfo(select, None)]
- self.distinct = True
- self.order_by = [1] if order == 'ASC' else [-1]
-
- if field.null:
- self.add_filter(("%s__isnull" % field_name, False))
-
- def _check_field(self, field):
- assert isinstance(field, DateField), \
- "%r isn't a DateField." % field.name
- if settings.USE_TZ:
- assert not isinstance(field, DateTimeField), \
- "%r is a DateTimeField, not a DateField." % field.name
-
- def _get_select(self, col, lookup_type):
- return Date(col, lookup_type)
-
-class DateTimeQuery(DateQuery):
- """
- A DateTimeQuery is like a DateQuery but for a datetime field. If time zone
- support is active, the tzinfo attribute contains the time zone to use for
- converting the values before truncating them. Otherwise it's set to None.
- """
-
- compiler = 'SQLDateTimeCompiler'
-
- def clone(self, klass=None, memo=None, **kwargs):
- if 'tzinfo' not in kwargs and hasattr(self, 'tzinfo'):
- kwargs['tzinfo'] = self.tzinfo
- return super(DateTimeQuery, self).clone(klass, memo, **kwargs)
-
- def _check_field(self, field):
- assert isinstance(field, DateTimeField), \
- "%r isn't a DateTimeField." % field.name
-
- def _get_select(self, col, lookup_type):
- if self.tzinfo is None:
- tzname = None
- else:
- tzname = timezone._get_timezone_name(self.tzinfo)
- return DateTime(col, lookup_type, tzname)
-
-class AggregateQuery(Query):
- """
- An AggregateQuery takes another query as a parameter to the FROM
- clause and only selects the elements in the provided list.
- """
-
- compiler = 'SQLAggregateCompiler'
-
- def add_subquery(self, query, using):
- self.subquery, self.sub_params = query.get_compiler(using).as_sql(with_col_aliases=True)
diff --git a/lib/python2.7/site-packages/django/db/models/sql/where.py b/lib/python2.7/site-packages/django/db/models/sql/where.py
deleted file mode 100644
index 2a342d4..0000000
--- a/lib/python2.7/site-packages/django/db/models/sql/where.py
+++ /dev/null
@@ -1,419 +0,0 @@
-"""
-Code to manage the creation and SQL rendering of 'where' constraints.
-"""
-
-from __future__ import absolute_import
-
-import datetime
-from itertools import repeat
-
-from django.conf import settings
-from django.db.models.fields import DateTimeField, Field
-from django.db.models.sql.datastructures import EmptyResultSet, Empty
-from django.db.models.sql.aggregates import Aggregate
-from django.utils.itercompat import is_iterator
-from django.utils.six.moves import xrange
-from django.utils import timezone
-from django.utils import tree
-
-# Connection types
-AND = 'AND'
-OR = 'OR'
-
-class EmptyShortCircuit(Exception):
- """
- Internal exception used to indicate that a "matches nothing" node should be
- added to the where-clause.
- """
- pass
-
-class WhereNode(tree.Node):
- """
- Used to represent the SQL where-clause.
-
- The class is tied to the Query class that created it (in order to create
- the correct SQL).
-
- A child is usually a tuple of:
- (Constraint(alias, targetcol, field), lookup_type, value)
- where value can be either raw Python value, or Query, ExpressionNode or
- something else knowing how to turn itself into SQL.
-
- However, a child could also be any class with as_sql() and either
- relabeled_clone() method or relabel_aliases() and clone() methods. The
- second alternative should be used if the alias is not the only mutable
- variable.
- """
- default = AND
-
- def _prepare_data(self, data):
- """
- Prepare data for addition to the tree. If the data is a list or tuple,
- it is expected to be of the form (obj, lookup_type, value), where obj
- is a Constraint object, and is then slightly munged before being
- stored (to avoid storing any reference to field objects). Otherwise,
- the 'data' is stored unchanged and can be any class with an 'as_sql()'
- method.
- """
- if not isinstance(data, (list, tuple)):
- return data
- obj, lookup_type, value = data
- if is_iterator(value):
- # Consume any generators immediately, so that we can determine
- # emptiness and transform any non-empty values correctly.
- value = list(value)
-
- # The "value_annotation" parameter is used to pass auxilliary information
- # about the value(s) to the query construction. Specifically, datetime
- # and empty values need special handling. Other types could be used
- # here in the future (using Python types is suggested for consistency).
- if (isinstance(value, datetime.datetime)
- or (isinstance(obj.field, DateTimeField) and lookup_type != 'isnull')):
- value_annotation = datetime.datetime
- elif hasattr(value, 'value_annotation'):
- value_annotation = value.value_annotation
- else:
- value_annotation = bool(value)
-
- if hasattr(obj, "prepare"):
- value = obj.prepare(lookup_type, value)
- return (obj, lookup_type, value_annotation, value)
-
- def as_sql(self, qn, connection):
- """
- Returns the SQL version of the where clause and the value to be
- substituted in. Returns '', [] if this node matches everything,
- None, [] if this node is empty, and raises EmptyResultSet if this
- node can't match anything.
- """
- # Note that the logic here is made slightly more complex than
- # necessary because there are two kind of empty nodes: Nodes
- # containing 0 children, and nodes that are known to match everything.
- # A match-everything node is different than empty node (which also
- # technically matches everything) for backwards compatibility reasons.
- # Refs #5261.
- result = []
- result_params = []
- everything_childs, nothing_childs = 0, 0
- non_empty_childs = len(self.children)
-
- for child in self.children:
- try:
- if hasattr(child, 'as_sql'):
- sql, params = child.as_sql(qn=qn, connection=connection)
- else:
- # A leaf node in the tree.
- sql, params = self.make_atom(child, qn, connection)
- except EmptyResultSet:
- nothing_childs += 1
- else:
- if sql:
- result.append(sql)
- result_params.extend(params)
- else:
- if sql is None:
- # Skip empty childs totally.
- non_empty_childs -= 1
- continue
- everything_childs += 1
- # Check if this node matches nothing or everything.
- # First check the amount of full nodes and empty nodes
- # to make this node empty/full.
- if self.connector == AND:
- full_needed, empty_needed = non_empty_childs, 1
- else:
- full_needed, empty_needed = 1, non_empty_childs
- # Now, check if this node is full/empty using the
- # counts.
- if empty_needed - nothing_childs <= 0:
- if self.negated:
- return '', []
- else:
- raise EmptyResultSet
- if full_needed - everything_childs <= 0:
- if self.negated:
- raise EmptyResultSet
- else:
- return '', []
-
- if non_empty_childs == 0:
- # All the child nodes were empty, so this one is empty, too.
- return None, []
- conn = ' %s ' % self.connector
- sql_string = conn.join(result)
- if sql_string:
- if self.negated:
- # Some backends (Oracle at least) need parentheses
- # around the inner SQL in the negated case, even if the
- # inner SQL contains just a single expression.
- sql_string = 'NOT (%s)' % sql_string
- elif len(result) > 1:
- sql_string = '(%s)' % sql_string
- return sql_string, result_params
-
- def get_cols(self):
- cols = []
- for child in self.children:
- if hasattr(child, 'get_cols'):
- cols.extend(child.get_cols())
- else:
- if isinstance(child[0], Constraint):
- cols.append((child[0].alias, child[0].col))
- if hasattr(child[3], 'get_cols'):
- cols.extend(child[3].get_cols())
- return cols
-
- def make_atom(self, child, qn, connection):
- """
- Turn a tuple (Constraint(table_alias, column_name, db_type),
- lookup_type, value_annotation, params) into valid SQL.
-
- The first item of the tuple may also be an Aggregate.
-
- Returns the string for the SQL fragment and the parameters to use for
- it.
- """
- lvalue, lookup_type, value_annotation, params_or_value = child
- field_internal_type = lvalue.field.get_internal_type() if lvalue.field else None
-
- if isinstance(lvalue, Constraint):
- try:
- lvalue, params = lvalue.process(lookup_type, params_or_value, connection)
- except EmptyShortCircuit:
- raise EmptyResultSet
- elif isinstance(lvalue, Aggregate):
- params = lvalue.field.get_db_prep_lookup(lookup_type, params_or_value, connection)
- else:
- raise TypeError("'make_atom' expects a Constraint or an Aggregate "
- "as the first item of its 'child' argument.")
-
- if isinstance(lvalue, tuple):
- # A direct database column lookup.
- field_sql, field_params = self.sql_for_columns(lvalue, qn, connection, field_internal_type), []
- else:
- # A smart object with an as_sql() method.
- field_sql, field_params = lvalue.as_sql(qn, connection)
-
- is_datetime_field = value_annotation is datetime.datetime
- cast_sql = connection.ops.datetime_cast_sql() if is_datetime_field else '%s'
-
- if hasattr(params, 'as_sql'):
- extra, params = params.as_sql(qn, connection)
- cast_sql = ''
- else:
- extra = ''
-
- params = field_params + params
-
- if (len(params) == 1 and params[0] == '' and lookup_type == 'exact'
- and connection.features.interprets_empty_strings_as_nulls):
- lookup_type = 'isnull'
- value_annotation = True
-
- if lookup_type in connection.operators:
- format = "%s %%s %%s" % (connection.ops.lookup_cast(lookup_type),)
- return (format % (field_sql,
- connection.operators[lookup_type] % cast_sql,
- extra), params)
-
- if lookup_type == 'in':
- if not value_annotation:
- raise EmptyResultSet
- if extra:
- return ('%s IN %s' % (field_sql, extra), params)
- max_in_list_size = connection.ops.max_in_list_size()
- if max_in_list_size and len(params) > max_in_list_size:
- # Break up the params list into an OR of manageable chunks.
- in_clause_elements = ['(']
- for offset in xrange(0, len(params), max_in_list_size):
- if offset > 0:
- in_clause_elements.append(' OR ')
- in_clause_elements.append('%s IN (' % field_sql)
- group_size = min(len(params) - offset, max_in_list_size)
- param_group = ', '.join(repeat('%s', group_size))
- in_clause_elements.append(param_group)
- in_clause_elements.append(')')
- in_clause_elements.append(')')
- return ''.join(in_clause_elements), params
- else:
- return ('%s IN (%s)' % (field_sql,
- ', '.join(repeat('%s', len(params)))),
- params)
- elif lookup_type in ('range', 'year'):
- return ('%s BETWEEN %%s and %%s' % field_sql, params)
- elif is_datetime_field and lookup_type in ('month', 'day', 'week_day',
- 'hour', 'minute', 'second'):
- tzname = timezone.get_current_timezone_name() if settings.USE_TZ else None
- sql, tz_params = connection.ops.datetime_extract_sql(lookup_type, field_sql, tzname)
- return ('%s = %%s' % sql, tz_params + params)
- elif lookup_type in ('month', 'day', 'week_day'):
- return ('%s = %%s'
- % connection.ops.date_extract_sql(lookup_type, field_sql), params)
- elif lookup_type == 'isnull':
- assert value_annotation in (True, False), "Invalid value_annotation for isnull"
- return ('%s IS %sNULL' % (field_sql, ('' if value_annotation else 'NOT ')), ())
- elif lookup_type == 'search':
- return (connection.ops.fulltext_search_sql(field_sql), params)
- elif lookup_type in ('regex', 'iregex'):
- return connection.ops.regex_lookup(lookup_type) % (field_sql, cast_sql), params
-
- raise TypeError('Invalid lookup_type: %r' % lookup_type)
-
- def sql_for_columns(self, data, qn, connection, internal_type=None):
- """
- Returns the SQL fragment used for the left-hand side of a column
- constraint (for example, the "T1.foo" portion in the clause
- "WHERE ... T1.foo = 6") and a list of parameters.
- """
- table_alias, name, db_type = data
- if table_alias:
- lhs = '%s.%s' % (qn(table_alias), qn(name))
- else:
- lhs = qn(name)
- return connection.ops.field_cast_sql(db_type, internal_type) % lhs
-
- def relabel_aliases(self, change_map):
- """
- Relabels the alias values of any children. 'change_map' is a dictionary
- mapping old (current) alias values to the new values.
- """
- for pos, child in enumerate(self.children):
- if hasattr(child, 'relabel_aliases'):
- # For example another WhereNode
- child.relabel_aliases(change_map)
- elif isinstance(child, (list, tuple)):
- # tuple starting with Constraint
- child = (child[0].relabeled_clone(change_map),) + child[1:]
- if hasattr(child[3], 'relabeled_clone'):
- child = (child[0], child[1], child[2]) + (
- child[3].relabeled_clone(change_map),)
- self.children[pos] = child
-
- def clone(self):
- """
- Creates a clone of the tree. Must only be called on root nodes (nodes
- with empty subtree_parents). Childs must be either (Contraint, lookup,
- value) tuples, or objects supporting .clone().
- """
- clone = self.__class__._new_instance(
- children=[], connector=self.connector, negated=self.negated)
- for child in self.children:
- if hasattr(child, 'clone'):
- clone.children.append(child.clone())
- else:
- clone.children.append(child)
- return clone
-
-class EmptyWhere(WhereNode):
-
- def add(self, data, connector):
- return
-
- def as_sql(self, qn=None, connection=None):
- raise EmptyResultSet
-
-class EverythingNode(object):
- """
- A node that matches everything.
- """
-
- def as_sql(self, qn=None, connection=None):
- return '', []
-
-
-class NothingNode(object):
- """
- A node that matches nothing.
- """
- def as_sql(self, qn=None, connection=None):
- raise EmptyResultSet
-
-
-class ExtraWhere(object):
- def __init__(self, sqls, params):
- self.sqls = sqls
- self.params = params
-
- def as_sql(self, qn=None, connection=None):
- sqls = ["(%s)" % sql for sql in self.sqls]
- return " AND ".join(sqls), list(self.params or ())
-
-
-class Constraint(object):
- """
- An object that can be passed to WhereNode.add() and knows how to
- pre-process itself prior to including in the WhereNode.
- """
- def __init__(self, alias, col, field):
- self.alias, self.col, self.field = alias, col, field
-
- def prepare(self, lookup_type, value):
- if self.field:
- return self.field.get_prep_lookup(lookup_type, value)
- return value
-
- def process(self, lookup_type, value, connection):
- """
- Returns a tuple of data suitable for inclusion in a WhereNode
- instance.
- """
- # Because of circular imports, we need to import this here.
- from django.db.models.base import ObjectDoesNotExist
- try:
- if self.field:
- params = self.field.get_db_prep_lookup(lookup_type, value,
- connection=connection, prepared=True)
- db_type = self.field.db_type(connection=connection)
- else:
- # This branch is used at times when we add a comparison to NULL
- # (we don't really want to waste time looking up the associated
- # field object at the calling location).
- params = Field().get_db_prep_lookup(lookup_type, value,
- connection=connection, prepared=True)
- db_type = None
- except ObjectDoesNotExist:
- raise EmptyShortCircuit
-
- return (self.alias, self.col, db_type), params
-
- def relabeled_clone(self, change_map):
- if self.alias not in change_map:
- return self
- else:
- new = Empty()
- new.__class__ = self.__class__
- new.alias, new.col, new.field = change_map[self.alias], self.col, self.field
- return new
-
-class SubqueryConstraint(object):
- def __init__(self, alias, columns, targets, query_object):
- self.alias = alias
- self.columns = columns
- self.targets = targets
- self.query_object = query_object
-
- def as_sql(self, qn, connection):
- query = self.query_object
-
- # QuerySet was sent
- if hasattr(query, 'values'):
- if query._db and connection.alias != query._db:
- raise ValueError("Can't do subqueries with queries on different DBs.")
- # Do not override already existing values.
- if not hasattr(query, 'field_names'):
- query = query.values(*self.targets)
- else:
- query = query._clone()
- query = query.query
- query.clear_ordering(True)
-
- query_compiler = query.get_compiler(connection=connection)
- return query_compiler.as_subquery_condition(self.alias, self.columns, qn)
-
- def relabel_aliases(self, change_map):
- self.alias = change_map.get(self.alias, self.alias)
-
- def clone(self):
- return self.__class__(
- self.alias, self.columns, self.targets,
- self.query_object)
diff --git a/lib/python2.7/site-packages/django/db/transaction.py b/lib/python2.7/site-packages/django/db/transaction.py
deleted file mode 100644
index f75137a..0000000
--- a/lib/python2.7/site-packages/django/db/transaction.py
+++ /dev/null
@@ -1,541 +0,0 @@
-"""
-This module implements a transaction manager that can be used to define
-transaction handling in a request or view function. It is used by transaction
-control middleware and decorators.
-
-The transaction manager can be in managed or in auto state. Auto state means the
-system is using a commit-on-save strategy (actually it's more like
-commit-on-change). As soon as the .save() or .delete() (or related) methods are
-called, a commit is made.
-
-Managed transactions don't do those commits, but will need some kind of manual
-or implicit commits or rollbacks.
-"""
-
-import warnings
-
-from functools import wraps
-
-from django.db import (
- connections, DEFAULT_DB_ALIAS,
- DatabaseError, Error, ProgrammingError)
-from django.utils.decorators import available_attrs
-
-
-class TransactionManagementError(ProgrammingError):
- """
- This exception is thrown when transaction management is used improperly.
- """
- pass
-
-################
-# Private APIs #
-################
-
-def get_connection(using=None):
- """
- Get a database connection by name, or the default database connection
- if no name is provided.
- """
- if using is None:
- using = DEFAULT_DB_ALIAS
- return connections[using]
-
-###########################
-# Deprecated private APIs #
-###########################
-
-def abort(using=None):
- """
- Roll back any ongoing transactions and clean the transaction management
- state of the connection.
-
- This method is to be used only in cases where using balanced
- leave_transaction_management() calls isn't possible. For example after a
- request has finished, the transaction state isn't known, yet the connection
- must be cleaned up for the next request.
- """
- get_connection(using).abort()
-
-def enter_transaction_management(managed=True, using=None, forced=False):
- """
- Enters transaction management for a running thread. It must be balanced with
- the appropriate leave_transaction_management call, since the actual state is
- managed as a stack.
-
- The state and dirty flag are carried over from the surrounding block or
- from the settings, if there is no surrounding block (dirty is always false
- when no current block is running).
- """
- get_connection(using).enter_transaction_management(managed, forced)
-
-def leave_transaction_management(using=None):
- """
- Leaves transaction management for a running thread. A dirty flag is carried
- over to the surrounding block, as a commit will commit all changes, even
- those from outside. (Commits are on connection level.)
- """
- get_connection(using).leave_transaction_management()
-
-def is_dirty(using=None):
- """
- Returns True if the current transaction requires a commit for changes to
- happen.
- """
- return get_connection(using).is_dirty()
-
-def set_dirty(using=None):
- """
- Sets a dirty flag for the current thread and code streak. This can be used
- to decide in a managed block of code to decide whether there are open
- changes waiting for commit.
- """
- get_connection(using).set_dirty()
-
-def set_clean(using=None):
- """
- Resets a dirty flag for the current thread and code streak. This can be used
- to decide in a managed block of code to decide whether a commit or rollback
- should happen.
- """
- get_connection(using).set_clean()
-
-def is_managed(using=None):
- warnings.warn("'is_managed' is deprecated.",
- PendingDeprecationWarning, stacklevel=2)
-
-def managed(flag=True, using=None):
- warnings.warn("'managed' no longer serves a purpose.",
- PendingDeprecationWarning, stacklevel=2)
-
-def commit_unless_managed(using=None):
- warnings.warn("'commit_unless_managed' is now a no-op.",
- PendingDeprecationWarning, stacklevel=2)
-
-def rollback_unless_managed(using=None):
- warnings.warn("'rollback_unless_managed' is now a no-op.",
- PendingDeprecationWarning, stacklevel=2)
-
-###############
-# Public APIs #
-###############
-
-def get_autocommit(using=None):
- """
- Get the autocommit status of the connection.
- """
- return get_connection(using).get_autocommit()
-
-def set_autocommit(autocommit, using=None):
- """
- Set the autocommit status of the connection.
- """
- return get_connection(using).set_autocommit(autocommit)
-
-def commit(using=None):
- """
- Commits a transaction and resets the dirty flag.
- """
- get_connection(using).commit()
-
-def rollback(using=None):
- """
- Rolls back a transaction and resets the dirty flag.
- """
- get_connection(using).rollback()
-
-def savepoint(using=None):
- """
- Creates a savepoint (if supported and required by the backend) inside the
- current transaction. Returns an identifier for the savepoint that will be
- used for the subsequent rollback or commit.
- """
- return get_connection(using).savepoint()
-
-def savepoint_rollback(sid, using=None):
- """
- Rolls back the most recent savepoint (if one exists). Does nothing if
- savepoints are not supported.
- """
- get_connection(using).savepoint_rollback(sid)
-
-def savepoint_commit(sid, using=None):
- """
- Commits the most recent savepoint (if one exists). Does nothing if
- savepoints are not supported.
- """
- get_connection(using).savepoint_commit(sid)
-
-def clean_savepoints(using=None):
- """
- Resets the counter used to generate unique savepoint ids in this thread.
- """
- get_connection(using).clean_savepoints()
-
-def get_rollback(using=None):
- """
- Gets the "needs rollback" flag -- for *advanced use* only.
- """
- return get_connection(using).get_rollback()
-
-def set_rollback(rollback, using=None):
- """
- Sets or unsets the "needs rollback" flag -- for *advanced use* only.
-
- When `rollback` is `True`, it triggers a rollback when exiting the
- innermost enclosing atomic block that has `savepoint=True` (that's the
- default). Use this to force a rollback without raising an exception.
-
- When `rollback` is `False`, it prevents such a rollback. Use this only
- after rolling back to a known-good state! Otherwise, you break the atomic
- block and data corruption may occur.
- """
- return get_connection(using).set_rollback(rollback)
-
-#################################
-# Decorators / context managers #
-#################################
-
-class Atomic(object):
- """
- This class guarantees the atomic execution of a given block.
-
- An instance can be used either as a decorator or as a context manager.
-
- When it's used as a decorator, __call__ wraps the execution of the
- decorated function in the instance itself, used as a context manager.
-
- When it's used as a context manager, __enter__ creates a transaction or a
- savepoint, depending on whether a transaction is already in progress, and
- __exit__ commits the transaction or releases the savepoint on normal exit,
- and rolls back the transaction or to the savepoint on exceptions.
-
- It's possible to disable the creation of savepoints if the goal is to
- ensure that some code runs within a transaction without creating overhead.
-
- A stack of savepoints identifiers is maintained as an attribute of the
- connection. None denotes the absence of a savepoint.
-
- This allows reentrancy even if the same AtomicWrapper is reused. For
- example, it's possible to define `oa = @atomic('other')` and use `@oa` or
- `with oa:` multiple times.
-
- Since database connections are thread-local, this is thread-safe.
- """
-
- def __init__(self, using, savepoint):
- self.using = using
- self.savepoint = savepoint
-
- def __enter__(self):
- connection = get_connection(self.using)
-
- if not connection.in_atomic_block:
- # Reset state when entering an outermost atomic block.
- connection.commit_on_exit = True
- connection.needs_rollback = False
- if not connection.get_autocommit():
- # Some database adapters (namely sqlite3) don't handle
- # transactions and savepoints properly when autocommit is off.
- # Turning autocommit back on isn't an option; it would trigger
- # a premature commit. Give up if that happens.
- if connection.features.autocommits_when_autocommit_is_off:
- raise TransactionManagementError(
- "Your database backend doesn't behave properly when "
- "autocommit is off. Turn it on before using 'atomic'.")
- # When entering an atomic block with autocommit turned off,
- # Django should only use savepoints and shouldn't commit.
- # This requires at least a savepoint for the outermost block.
- if not self.savepoint:
- raise TransactionManagementError(
- "The outermost 'atomic' block cannot use "
- "savepoint = False when autocommit is off.")
- # Pretend we're already in an atomic block to bypass the code
- # that disables autocommit to enter a transaction, and make a
- # note to deal with this case in __exit__.
- connection.in_atomic_block = True
- connection.commit_on_exit = False
-
- if connection.in_atomic_block:
- # We're already in a transaction; create a savepoint, unless we
- # were told not to or we're already waiting for a rollback. The
- # second condition avoids creating useless savepoints and prevents
- # overwriting needs_rollback until the rollback is performed.
- if self.savepoint and not connection.needs_rollback:
- sid = connection.savepoint()
- connection.savepoint_ids.append(sid)
- else:
- connection.savepoint_ids.append(None)
- else:
- # We aren't in a transaction yet; create one.
- # The usual way to start a transaction is to turn autocommit off.
- # However, some database adapters (namely sqlite3) don't handle
- # transactions and savepoints properly when autocommit is off.
- # In such cases, start an explicit transaction instead, which has
- # the side-effect of disabling autocommit.
- if connection.features.autocommits_when_autocommit_is_off:
- connection._start_transaction_under_autocommit()
- connection.autocommit = False
- else:
- connection.set_autocommit(False)
- connection.in_atomic_block = True
-
- def __exit__(self, exc_type, exc_value, traceback):
- connection = get_connection(self.using)
-
- if connection.savepoint_ids:
- sid = connection.savepoint_ids.pop()
- else:
- # Prematurely unset this flag to allow using commit or rollback.
- connection.in_atomic_block = False
-
- try:
- if connection.closed_in_transaction:
- # The database will perform a rollback by itself.
- # Wait until we exit the outermost block.
- pass
-
- elif exc_type is None and not connection.needs_rollback:
- if connection.in_atomic_block:
- # Release savepoint if there is one
- if sid is not None:
- try:
- connection.savepoint_commit(sid)
- except DatabaseError:
- try:
- connection.savepoint_rollback(sid)
- except Error:
- # If rolling back to a savepoint fails, mark for
- # rollback at a higher level and avoid shadowing
- # the original exception.
- connection.needs_rollback = True
- raise
- else:
- # Commit transaction
- try:
- connection.commit()
- except DatabaseError:
- try:
- connection.rollback()
- except Error:
- # An error during rollback means that something
- # went wrong with the connection. Drop it.
- connection.close()
- raise
- else:
- # This flag will be set to True again if there isn't a savepoint
- # allowing to perform the rollback at this level.
- connection.needs_rollback = False
- if connection.in_atomic_block:
- # Roll back to savepoint if there is one, mark for rollback
- # otherwise.
- if sid is None:
- connection.needs_rollback = True
- else:
- try:
- connection.savepoint_rollback(sid)
- except Error:
- # If rolling back to a savepoint fails, mark for
- # rollback at a higher level and avoid shadowing
- # the original exception.
- connection.needs_rollback = True
- else:
- # Roll back transaction
- try:
- connection.rollback()
- except Error:
- # An error during rollback means that something
- # went wrong with the connection. Drop it.
- connection.close()
-
- finally:
- # Outermost block exit when autocommit was enabled.
- if not connection.in_atomic_block:
- if connection.closed_in_transaction:
- connection.connection = None
- elif connection.features.autocommits_when_autocommit_is_off:
- connection.autocommit = True
- else:
- connection.set_autocommit(True)
- # Outermost block exit when autocommit was disabled.
- elif not connection.savepoint_ids and not connection.commit_on_exit:
- if connection.closed_in_transaction:
- connection.connection = None
- else:
- connection.in_atomic_block = False
-
- def __call__(self, func):
- @wraps(func, assigned=available_attrs(func))
- def inner(*args, **kwargs):
- with self:
- return func(*args, **kwargs)
- return inner
-
-
-def atomic(using=None, savepoint=True):
- # Bare decorator: @atomic -- although the first argument is called
- # `using`, it's actually the function being decorated.
- if callable(using):
- return Atomic(DEFAULT_DB_ALIAS, savepoint)(using)
- # Decorator: @atomic(...) or context manager: with atomic(...): ...
- else:
- return Atomic(using, savepoint)
-
-
-def _non_atomic_requests(view, using):
- try:
- view._non_atomic_requests.add(using)
- except AttributeError:
- view._non_atomic_requests = set([using])
- return view
-
-
-def non_atomic_requests(using=None):
- if callable(using):
- return _non_atomic_requests(using, DEFAULT_DB_ALIAS)
- else:
- if using is None:
- using = DEFAULT_DB_ALIAS
- return lambda view: _non_atomic_requests(view, using)
-
-
-############################################
-# Deprecated decorators / context managers #
-############################################
-
-class Transaction(object):
- """
- Acts as either a decorator, or a context manager. If it's a decorator it
- takes a function and returns a wrapped function. If it's a contextmanager
- it's used with the ``with`` statement. In either event entering/exiting
- are called before and after, respectively, the function/block is executed.
-
- autocommit, commit_on_success, and commit_manually contain the
- implementations of entering and exiting.
- """
- def __init__(self, entering, exiting, using):
- self.entering = entering
- self.exiting = exiting
- self.using = using
-
- def __enter__(self):
- self.entering(self.using)
-
- def __exit__(self, exc_type, exc_value, traceback):
- self.exiting(exc_type, self.using)
-
- def __call__(self, func):
- @wraps(func)
- def inner(*args, **kwargs):
- with self:
- return func(*args, **kwargs)
- return inner
-
-def _transaction_func(entering, exiting, using):
- """
- Takes 3 things, an entering function (what to do to start this block of
- transaction management), an exiting function (what to do to end it, on both
- success and failure, and using which can be: None, indiciating using is
- DEFAULT_DB_ALIAS, a callable, indicating that using is DEFAULT_DB_ALIAS and
- to return the function already wrapped.
-
- Returns either a Transaction objects, which is both a decorator and a
- context manager, or a wrapped function, if using is a callable.
- """
- # Note that although the first argument is *called* `using`, it
- # may actually be a function; @autocommit and @autocommit('foo')
- # are both allowed forms.
- if using is None:
- using = DEFAULT_DB_ALIAS
- if callable(using):
- return Transaction(entering, exiting, DEFAULT_DB_ALIAS)(using)
- return Transaction(entering, exiting, using)
-
-
-def autocommit(using=None):
- """
- Decorator that activates commit on save. This is Django's default behavior;
- this decorator is useful if you globally activated transaction management in
- your settings file and want the default behavior in some view functions.
- """
- warnings.warn("autocommit is deprecated in favor of set_autocommit.",
- PendingDeprecationWarning, stacklevel=2)
-
- def entering(using):
- enter_transaction_management(managed=False, using=using)
-
- def exiting(exc_type, using):
- leave_transaction_management(using=using)
-
- return _transaction_func(entering, exiting, using)
-
-def commit_on_success(using=None):
- """
- This decorator activates commit on response. This way, if the view function
- runs successfully, a commit is made; if the viewfunc produces an exception,
- a rollback is made. This is one of the most common ways to do transaction
- control in Web apps.
- """
- warnings.warn("commit_on_success is deprecated in favor of atomic.",
- PendingDeprecationWarning, stacklevel=2)
-
- def entering(using):
- enter_transaction_management(using=using)
-
- def exiting(exc_type, using):
- try:
- if exc_type is not None:
- if is_dirty(using=using):
- rollback(using=using)
- else:
- if is_dirty(using=using):
- try:
- commit(using=using)
- except:
- rollback(using=using)
- raise
- finally:
- leave_transaction_management(using=using)
-
- return _transaction_func(entering, exiting, using)
-
-def commit_manually(using=None):
- """
- Decorator that activates manual transaction control. It just disables
- automatic transaction control and doesn't do any commit/rollback of its
- own -- it's up to the user to call the commit and rollback functions
- themselves.
- """
- warnings.warn("commit_manually is deprecated in favor of set_autocommit.",
- PendingDeprecationWarning, stacklevel=2)
-
- def entering(using):
- enter_transaction_management(using=using)
-
- def exiting(exc_type, using):
- leave_transaction_management(using=using)
-
- return _transaction_func(entering, exiting, using)
-
-def commit_on_success_unless_managed(using=None, savepoint=False):
- """
- Transitory API to preserve backwards-compatibility while refactoring.
-
- Once the legacy transaction management is fully deprecated, this should
- simply be replaced by atomic. Until then, it's necessary to guarantee that
- a commit occurs on exit, which atomic doesn't do when it's nested.
-
- Unlike atomic, savepoint defaults to False because that's closer to the
- legacy behavior.
- """
- connection = get_connection(using)
- if connection.get_autocommit() or connection.in_atomic_block:
- return atomic(using, savepoint)
- else:
- def entering(using):
- pass
-
- def exiting(exc_type, using):
- set_dirty(using=using)
-
- return _transaction_func(entering, exiting, using)
diff --git a/lib/python2.7/site-packages/django/db/utils.py b/lib/python2.7/site-packages/django/db/utils.py
deleted file mode 100644
index eb5708c..0000000
--- a/lib/python2.7/site-packages/django/db/utils.py
+++ /dev/null
@@ -1,282 +0,0 @@
-from functools import wraps
-import os
-import pkgutil
-from threading import local
-import warnings
-
-from django.conf import settings
-from django.core.exceptions import ImproperlyConfigured
-from django.utils.functional import cached_property
-from django.utils.importlib import import_module
-from django.utils.module_loading import import_by_path
-from django.utils._os import upath
-from django.utils import six
-
-
-DEFAULT_DB_ALIAS = 'default'
-
-
-class Error(Exception if six.PY3 else StandardError):
- pass
-
-
-class InterfaceError(Error):
- pass
-
-
-class DatabaseError(Error):
- pass
-
-
-class DataError(DatabaseError):
- pass
-
-
-class OperationalError(DatabaseError):
- pass
-
-
-class IntegrityError(DatabaseError):
- pass
-
-
-class InternalError(DatabaseError):
- pass
-
-
-class ProgrammingError(DatabaseError):
- pass
-
-
-class NotSupportedError(DatabaseError):
- pass
-
-
-class DatabaseErrorWrapper(object):
- """
- Context manager and decorator that re-throws backend-specific database
- exceptions using Django's common wrappers.
- """
-
- def __init__(self, wrapper):
- """
- wrapper is a database wrapper.
-
- It must have a Database attribute defining PEP-249 exceptions.
- """
- self.wrapper = wrapper
-
- def __enter__(self):
- pass
-
- def __exit__(self, exc_type, exc_value, traceback):
- if exc_type is None:
- return
- for dj_exc_type in (
- DataError,
- OperationalError,
- IntegrityError,
- InternalError,
- ProgrammingError,
- NotSupportedError,
- DatabaseError,
- InterfaceError,
- Error,
- ):
- db_exc_type = getattr(self.wrapper.Database, dj_exc_type.__name__)
- if issubclass(exc_type, db_exc_type):
- # Under Python 2.6, exc_value can still be a string.
- try:
- args = tuple(exc_value.args)
- except AttributeError:
- args = (exc_value,)
- dj_exc_value = dj_exc_type(*args)
- dj_exc_value.__cause__ = exc_value
- # Only set the 'errors_occurred' flag for errors that may make
- # the connection unusable.
- if dj_exc_type not in (DataError, IntegrityError):
- self.wrapper.errors_occurred = True
- six.reraise(dj_exc_type, dj_exc_value, traceback)
-
- def __call__(self, func):
- # Note that we are intentionally not using @wraps here for performance
- # reasons. Refs #21109.
- def inner(*args, **kwargs):
- with self:
- return func(*args, **kwargs)
- return inner
-
-
-def load_backend(backend_name):
- # Look for a fully qualified database backend name
- try:
- return import_module('%s.base' % backend_name)
- except ImportError as e_user:
- # The database backend wasn't found. Display a helpful error message
- # listing all possible (built-in) database backends.
- backend_dir = os.path.join(os.path.dirname(upath(__file__)), 'backends')
- try:
- builtin_backends = [
- name for _, name, ispkg in pkgutil.iter_modules([backend_dir])
- if ispkg and name != 'dummy']
- except EnvironmentError:
- builtin_backends = []
- if backend_name not in ['django.db.backends.%s' % b for b in
- builtin_backends]:
- backend_reprs = map(repr, sorted(builtin_backends))
- error_msg = ("%r isn't an available database backend.\n"
- "Try using 'django.db.backends.XXX', where XXX "
- "is one of:\n %s\nError was: %s" %
- (backend_name, ", ".join(backend_reprs), e_user))
- raise ImproperlyConfigured(error_msg)
- else:
- # If there's some other error, this must be an error in Django
- raise
-
-
-class ConnectionDoesNotExist(Exception):
- pass
-
-
-class ConnectionHandler(object):
- def __init__(self, databases=None):
- """
- databases is an optional dictionary of database definitions (structured
- like settings.DATABASES).
- """
- self._databases = databases
- self._connections = local()
-
- @cached_property
- def databases(self):
- if self._databases is None:
- self._databases = settings.DATABASES
- if self._databases == {}:
- self._databases = {
- DEFAULT_DB_ALIAS: {
- 'ENGINE': 'django.db.backends.dummy',
- },
- }
- if DEFAULT_DB_ALIAS not in self._databases:
- raise ImproperlyConfigured("You must define a '%s' database" % DEFAULT_DB_ALIAS)
- return self._databases
-
- def ensure_defaults(self, alias):
- """
- Puts the defaults into the settings dictionary for a given connection
- where no settings is provided.
- """
- try:
- conn = self.databases[alias]
- except KeyError:
- raise ConnectionDoesNotExist("The connection %s doesn't exist" % alias)
-
- conn.setdefault('ATOMIC_REQUESTS', False)
- if settings.TRANSACTIONS_MANAGED:
- warnings.warn(
- "TRANSACTIONS_MANAGED is deprecated. Use AUTOCOMMIT instead.",
- PendingDeprecationWarning, stacklevel=2)
- conn.setdefault('AUTOCOMMIT', False)
- conn.setdefault('AUTOCOMMIT', True)
- conn.setdefault('ENGINE', 'django.db.backends.dummy')
- if conn['ENGINE'] == 'django.db.backends.' or not conn['ENGINE']:
- conn['ENGINE'] = 'django.db.backends.dummy'
- conn.setdefault('CONN_MAX_AGE', 0)
- conn.setdefault('OPTIONS', {})
- conn.setdefault('TIME_ZONE', 'UTC' if settings.USE_TZ else settings.TIME_ZONE)
- for setting in ['NAME', 'USER', 'PASSWORD', 'HOST', 'PORT']:
- conn.setdefault(setting, '')
- for setting in ['TEST_CHARSET', 'TEST_COLLATION', 'TEST_NAME', 'TEST_MIRROR']:
- conn.setdefault(setting, None)
-
- def __getitem__(self, alias):
- if hasattr(self._connections, alias):
- return getattr(self._connections, alias)
-
- self.ensure_defaults(alias)
- db = self.databases[alias]
- backend = load_backend(db['ENGINE'])
- conn = backend.DatabaseWrapper(db, alias)
- setattr(self._connections, alias, conn)
- return conn
-
- def __setitem__(self, key, value):
- setattr(self._connections, key, value)
-
- def __delitem__(self, key):
- delattr(self._connections, key)
-
- def __iter__(self):
- return iter(self.databases)
-
- def all(self):
- return [self[alias] for alias in self]
-
-
-class ConnectionRouter(object):
- def __init__(self, routers=None):
- """
- If routers is not specified, will default to settings.DATABASE_ROUTERS.
- """
- self._routers = routers
-
- @cached_property
- def routers(self):
- if self._routers is None:
- self._routers = settings.DATABASE_ROUTERS
- routers = []
- for r in self._routers:
- if isinstance(r, six.string_types):
- router = import_by_path(r)()
- else:
- router = r
- routers.append(router)
- return routers
-
- def _router_func(action):
- def _route_db(self, model, **hints):
- chosen_db = None
- for router in self.routers:
- try:
- method = getattr(router, action)
- except AttributeError:
- # If the router doesn't have a method, skip to the next one.
- pass
- else:
- chosen_db = method(model, **hints)
- if chosen_db:
- return chosen_db
- try:
- return hints['instance']._state.db or DEFAULT_DB_ALIAS
- except KeyError:
- return DEFAULT_DB_ALIAS
- return _route_db
-
- db_for_read = _router_func('db_for_read')
- db_for_write = _router_func('db_for_write')
-
- def allow_relation(self, obj1, obj2, **hints):
- for router in self.routers:
- try:
- method = router.allow_relation
- except AttributeError:
- # If the router doesn't have a method, skip to the next one.
- pass
- else:
- allow = method(obj1, obj2, **hints)
- if allow is not None:
- return allow
- return obj1._state.db == obj2._state.db
-
- def allow_syncdb(self, db, model):
- for router in self.routers:
- try:
- method = router.allow_syncdb
- except AttributeError:
- # If the router doesn't have a method, skip to the next one.
- pass
- else:
- allow = method(db, model)
- if allow is not None:
- return allow
- return True