summaryrefslogtreecommitdiff
path: root/django/db
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2012-08-10 12:40:37 +0100
committerAndrew Godwin <andrew@aeracode.org>2012-08-10 12:40:37 +0100
commit184cf9ab798d5b25d855649ddb2ca580949778df (patch)
tree8512633ec04a6979b0953e32e73c9a43d09e5805 /django/db
parentc4b2a3262cc79383d6562cfc7e9af20135c8e0bf (diff)
parent7275576235ae2e87f3de7b0facb3f9b0a2368f28 (diff)
Merge branch 'master' into schema-alteration
Diffstat (limited to 'django/db')
-rw-r--r--django/db/backends/__init__.py10
-rw-r--r--django/db/backends/creation.py3
-rw-r--r--django/db/backends/mysql/introspection.py3
-rw-r--r--django/db/backends/oracle/base.py22
-rw-r--r--django/db/backends/oracle/creation.py5
-rw-r--r--django/db/backends/sqlite3/base.py16
-rw-r--r--django/db/backends/sqlite3/creation.py3
-rw-r--r--django/db/models/base.py65
-rw-r--r--django/db/models/deletion.py25
-rw-r--r--django/db/models/fields/__init__.py21
-rw-r--r--django/db/models/fields/files.py4
-rw-r--r--django/db/models/fields/related.py14
-rw-r--r--django/db/models/loading.py5
-rw-r--r--django/db/models/options.py23
-rw-r--r--django/db/models/query.py23
-rw-r--r--django/db/models/query_utils.py5
-rw-r--r--django/db/models/related.py6
-rw-r--r--django/db/models/sql/compiler.py7
-rw-r--r--django/db/models/sql/query.py29
-rw-r--r--django/db/models/sql/subqueries.py11
20 files changed, 158 insertions, 142 deletions
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index b9c642d093..5719f51445 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -621,16 +621,16 @@ class BaseDatabaseOperations(object):
exists for database backends to provide a better implementation
according to their own quoting schemes.
"""
- from django.utils.encoding import smart_unicode, force_unicode
+ from django.utils.encoding import smart_text, force_text
# Convert params to contain Unicode values.
- to_unicode = lambda s: force_unicode(s, strings_only=True, errors='replace')
+ 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])
else:
u_params = dict([(to_unicode(k), to_unicode(v)) for k, v in params.items()])
- return smart_unicode(sql) % u_params
+ return smart_text(sql) % u_params
def last_insert_id(self, cursor, table_name, pk_name):
"""
@@ -814,8 +814,8 @@ class BaseDatabaseOperations(object):
def prep_for_like_query(self, x):
"""Prepares a value for use in a LIKE query."""
- from django.utils.encoding import smart_unicode
- return smart_unicode(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
+ from django.utils.encoding import smart_text
+ return smart_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.
diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index 4dffd78f44..0cc01cc876 100644
--- a/django/db/backends/creation.py
+++ b/django/db/backends/creation.py
@@ -3,6 +3,7 @@ import time
from django.conf import settings
from django.db.utils import load_backend
+from django.utils.six.moves import input
# The prefix to put on the default database name when creating
# the test database.
@@ -331,7 +332,7 @@ class BaseDatabaseCreation(object):
sys.stderr.write(
"Got an error creating the test database: %s\n" % e)
if not autoclobber:
- confirm = raw_input(
+ 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':
diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py
index e6f18b819f..6aab0b99ab 100644
--- a/django/db/backends/mysql/introspection.py
+++ b/django/db/backends/mysql/introspection.py
@@ -1,4 +1,5 @@
from django.db.backends import BaseDatabaseIntrospection
+from django.utils import six
from MySQLdb import ProgrammingError, OperationalError
from MySQLdb.constants import FIELD_TYPE
import re
@@ -79,7 +80,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
"""
Returns the name of the primary key column for the given table
"""
- for column in self.get_indexes(cursor, table_name).iteritems():
+ for column in six.iteritems(self.get_indexes(cursor, table_name)):
if column[1]['primary_key']:
return column[0]
return None
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index b08113fed7..89cad12b6c 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -53,7 +53,7 @@ from django.db.backends.signals import connection_created
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 smart_str, force_unicode
+from django.utils.encoding import smart_bytes, force_text
from django.utils import six
from django.utils import timezone
@@ -64,9 +64,9 @@ IntegrityError = Database.IntegrityError
# Check whether cx_Oracle was compiled with the WITH_UNICODE option. This will
# also be True in Python 3.0.
if int(Database.version.split('.', 1)[0]) >= 5 and not hasattr(Database, 'UNICODE'):
- convert_unicode = force_unicode
+ convert_unicode = force_text
else:
- convert_unicode = smart_str
+ convert_unicode = smart_bytes
class DatabaseFeatures(BaseDatabaseFeatures):
@@ -162,7 +162,7 @@ WHEN (new.%(col_name)s IS NULL)
if isinstance(value, Database.LOB):
value = value.read()
if field and field.get_internal_type() == 'TextField':
- value = force_unicode(value)
+ 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
@@ -245,7 +245,7 @@ WHEN (new.%(col_name)s IS NULL)
def process_clob(self, value):
if value is None:
return ''
- return force_unicode(value.read())
+ return force_text(value.read())
def quote_name(self, name):
# SQL92 requires delimited (quoted) names to be case-sensitive. When
@@ -595,9 +595,9 @@ class OracleParam(object):
param = param.astimezone(timezone.utc).replace(tzinfo=None)
if hasattr(param, 'bind_parameter'):
- self.smart_str = param.bind_parameter(cursor)
+ self.smart_bytes = param.bind_parameter(cursor)
else:
- self.smart_str = convert_unicode(param, cursor.charset,
+ self.smart_bytes = convert_unicode(param, cursor.charset,
strings_only)
if hasattr(param, 'input_size'):
# If parameter has `input_size` attribute, use that.
@@ -676,7 +676,7 @@ class FormatStylePlaceholderCursor(object):
self.setinputsizes(*sizes)
def _param_generator(self, params):
- return [p.smart_str for p in params]
+ return [p.smart_bytes for p in params]
def execute(self, query, params=None):
if params is None:
@@ -774,9 +774,11 @@ class CursorIterator(object):
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
return _rowfactory(next(self.iter), self.cursor)
+ next = __next__ # Python 2 compatibility
+
def _rowfactory(row, cursor):
# Cast numeric values as the appropriate Python type based upon the
@@ -831,7 +833,7 @@ def to_unicode(s):
unchanged).
"""
if isinstance(s, six.string_types):
- return force_unicode(s)
+ return force_text(s)
return s
diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py
index 2f096f735a..d9bf3dfea2 100644
--- a/django/db/backends/oracle/creation.py
+++ b/django/db/backends/oracle/creation.py
@@ -1,6 +1,7 @@
import sys
import time
from django.db.backends.creation import BaseDatabaseCreation
+from django.utils.six.moves import input
TEST_DATABASE_PREFIX = 'test_'
PASSWORD = 'Im_a_lumberjack'
@@ -65,7 +66,7 @@ class DatabaseCreation(BaseDatabaseCreation):
except Exception as e:
sys.stderr.write("Got an error creating the test database: %s\n" % e)
if not autoclobber:
- confirm = raw_input("It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_NAME)
+ 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:
@@ -87,7 +88,7 @@ class DatabaseCreation(BaseDatabaseCreation):
except Exception as e:
sys.stderr.write("Got an error creating the test user: %s\n" % e)
if not autoclobber:
- confirm = raw_input("It appears the test user, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: " % TEST_USER)
+ 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:
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 0a97449789..0880079189 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -54,15 +54,15 @@ def adapt_datetime_with_timezone_support(value):
default_timezone = timezone.get_default_timezone()
value = timezone.make_aware(value, default_timezone)
value = value.astimezone(timezone.utc).replace(tzinfo=None)
- return value.isoformat(b" ")
+ return value.isoformat(str(" "))
-Database.register_converter(b"bool", lambda s: str(s) == '1')
-Database.register_converter(b"time", parse_time)
-Database.register_converter(b"date", parse_date)
-Database.register_converter(b"datetime", parse_datetime_with_timezone_support)
-Database.register_converter(b"timestamp", parse_datetime_with_timezone_support)
-Database.register_converter(b"TIMESTAMP", parse_datetime_with_timezone_support)
-Database.register_converter(b"decimal", util.typecast_decimal)
+Database.register_converter(str("bool"), lambda s: str(s) == '1')
+Database.register_converter(str("time"), parse_time)
+Database.register_converter(str("date"), parse_date)
+Database.register_converter(str("datetime"), parse_datetime_with_timezone_support)
+Database.register_converter(str("timestamp"), parse_datetime_with_timezone_support)
+Database.register_converter(str("TIMESTAMP"), parse_datetime_with_timezone_support)
+Database.register_converter(str("decimal"), util.typecast_decimal)
Database.register_adapter(datetime.datetime, adapt_datetime_with_timezone_support)
Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
if Database.version_info >= (2, 4, 1):
diff --git a/django/db/backends/sqlite3/creation.py b/django/db/backends/sqlite3/creation.py
index efdc457be0..c022b56c85 100644
--- a/django/db/backends/sqlite3/creation.py
+++ b/django/db/backends/sqlite3/creation.py
@@ -1,6 +1,7 @@
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
@@ -53,7 +54,7 @@ class DatabaseCreation(BaseDatabaseCreation):
print("Destroying old test database '%s'..." % self.connection.alias)
if os.access(test_database_name, os.F_OK):
if not autoclobber:
- confirm = raw_input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % test_database_name)
+ 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)
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 002e2aff65..569b8e876c 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -23,11 +23,35 @@ 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 smart_str, force_unicode
+from django.utils.encoding import smart_bytes, 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.
@@ -63,12 +87,12 @@ class ModelBase(type):
new_class.add_to_class('_meta', Options(meta, **kwargs))
if not abstract:
- new_class.add_to_class('DoesNotExist', subclass_exception(b'DoesNotExist',
+ 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(b'MultipleObjectsReturned',
+ 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,),
@@ -364,14 +388,14 @@ class Model(six.with_metaclass(ModelBase, object)):
setattr(self, field.attname, val)
if kwargs:
- for prop in kwargs.keys():
+ 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" % kwargs.keys()[0])
+ 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)
@@ -380,11 +404,11 @@ class Model(six.with_metaclass(ModelBase, object)):
u = six.text_type(self)
except (UnicodeEncodeError, UnicodeDecodeError):
u = '[Bad Unicode data]'
- return smart_str('<%s: %s>' % (self.__class__.__name__, u))
+ return smart_bytes('<%s: %s>' % (self.__class__.__name__, u))
def __str__(self):
if hasattr(self, '__unicode__'):
- return force_unicode(self).encode('utf-8')
+ return force_text(self).encode('utf-8')
return '%s object' % self.__class__.__name__
def __eq__(self, other):
@@ -605,14 +629,14 @@ class Model(six.with_metaclass(ModelBase, object)):
def _get_FIELD_display(self, field):
value = getattr(self, field.attname)
- return force_unicode(dict(field.flatchoices).get(value, value), strings_only=True)
+ 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 = is_next and 'gt' or 'lt'
order = not is_next and '-' or ''
- param = smart_str(getattr(self, field.attname))
+ param = smart_bytes(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)
@@ -929,29 +953,6 @@ def model_unpickle(model, attrs):
return cls.__new__(cls)
model_unpickle.__safe_for_unpickle__ = True
-def subclass_exception(name, parents, module, attached_to=None):
- """
- Create exception subclass.
-
- 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)
-
def unpickle_inner_exception(klass, exception_name):
# Get the exception class from the class it is attached to:
exception = getattr(klass, exception_name)
diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py
index d8bb8f2e66..4449b75a81 100644
--- a/django/db/models/deletion.py
+++ b/django/db/models/deletion.py
@@ -4,6 +4,7 @@ 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):
@@ -157,7 +158,7 @@ class Collector(object):
# 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 concrete_model._meta.parents.itervalues():
+ for ptr in six.itervalues(concrete_model._meta.parents):
if ptr:
parent_objs = [getattr(obj, ptr.name) for obj in new_objs]
self.collect(parent_objs, source=model,
@@ -199,14 +200,14 @@ class Collector(object):
)
def instances_with_model(self):
- for model, instances in self.data.iteritems():
+ for model, instances in six.iteritems(self.data):
for obj in instances:
yield model, obj
def sort(self):
sorted_models = []
concrete_models = set()
- models = self.data.keys()
+ models = list(self.data)
while len(sorted_models) < len(models):
found = False
for model in models:
@@ -241,24 +242,24 @@ class Collector(object):
)
# update fields
- for model, instances_for_fieldvalues in self.field_updates.iteritems():
+ for model, instances_for_fieldvalues in six.iteritems(self.field_updates):
query = sql.UpdateQuery(model)
- for (field, value), instances in instances_for_fieldvalues.iteritems():
+ 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 self.data.itervalues():
+ for instances in six.itervalues(self.data):
instances.reverse()
# delete batches
- for model, batches in self.batches.iteritems():
+ for model, batches in six.iteritems(self.batches):
query = sql.DeleteQuery(model)
- for field, instances in batches.iteritems():
+ for field, instances in six.iteritems(batches):
query.delete_batch([obj.pk for obj in instances], self.using, field)
# delete instances
- for model, instances in self.data.iteritems():
+ 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)
@@ -271,10 +272,10 @@ class Collector(object):
)
# update collected instances
- for model, instances_for_fieldvalues in self.field_updates.iteritems():
- for (field, value), instances in instances_for_fieldvalues.iteritems():
+ 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 self.data.iteritems():
+ for model, instances in six.iteritems(self.data):
for instance in instances:
setattr(instance, model._meta.pk.attname, None)
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 9606b1b843..d07851bbf5 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -19,7 +19,7 @@ from django.utils.functional import curry, total_ordering
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_unicode, force_unicode
+from django.utils.encoding import smart_text, force_text
from django.utils.ipv6 import clean_ipv6_address
from django.utils import six
@@ -135,6 +135,8 @@ class Field(object):
return self.creation_counter < other.creation_counter
return NotImplemented
+ __hash__ = object.__hash__
+
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.
@@ -179,7 +181,8 @@ class Field(object):
if not self.editable:
# Skip validation for non-editable fields.
return
- if self._choices and value:
+
+ if self._choices and value not in validators.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
@@ -385,7 +388,7 @@ class Field(object):
if self.has_default():
if callable(self.default):
return self.default()
- return force_unicode(self.default, strings_only=True)
+ 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
@@ -403,11 +406,11 @@ class Field(object):
rel_model = self.rel.to
if hasattr(self.rel, 'get_related_field'):
lst = [(getattr(x, self.rel.get_related_field().attname),
- smart_unicode(x))
+ smart_text(x))
for x in rel_model._default_manager.complex_filter(
self.rel.limit_choices_to)]
else:
- lst = [(x._get_pk_val(), smart_unicode(x))
+ 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
@@ -434,7 +437,7 @@ class Field(object):
Returns a string value of this field from the passed obj.
This is used by the serialization framework.
"""
- return smart_unicode(self._get_val_from_obj(obj))
+ return smart_text(self._get_val_from_obj(obj))
def bind(self, fieldmapping, original, bound_field_class):
return bound_field_class(self, fieldmapping, original)
@@ -486,7 +489,7 @@ class Field(object):
# 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 kwargs.keys():
+ for k in list(kwargs):
if k not in ('coerce', 'empty_value', 'choices', 'required',
'widget', 'label', 'initial', 'help_text',
'error_messages', 'show_hidden_initial'):
@@ -628,7 +631,7 @@ class CharField(Field):
def to_python(self, value):
if isinstance(value, six.string_types) or value is None:
return value
- return smart_unicode(value)
+ return smart_text(value)
def get_prep_value(self, value):
return self.to_python(value)
@@ -1188,7 +1191,7 @@ class TextField(Field):
def get_prep_value(self, value):
if isinstance(value, six.string_types) or value is None:
return value
- return smart_unicode(value)
+ return smart_text(value)
def formfield(self, **kwargs):
defaults = {'widget': forms.Textarea}
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index b51ef1d5d6..ad4c36ca0d 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -8,7 +8,7 @@ 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_unicode, smart_str
+from django.utils.encoding import force_text, smart_bytes
from django.utils import six
from django.utils.translation import ugettext_lazy as _
@@ -280,7 +280,7 @@ class FileField(Field):
setattr(cls, self.name, self.descriptor_class(self))
def get_directory_name(self):
- return os.path.normpath(force_unicode(datetime.datetime.now().strftime(smart_str(self.upload_to))))
+ return os.path.normpath(force_text(datetime.datetime.now().strftime(smart_bytes(self.upload_to))))
def get_filename(self, filename):
return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 2a2502b54f..08cc0a747f 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -9,7 +9,7 @@ from django.db.models.related import RelatedObject
from django.db.models.query import QuerySet
from django.db.models.query_utils import QueryWrapper
from django.db.models.deletion import CASCADE
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
from django.utils import six
from django.utils.translation import ugettext_lazy as _, string_concat
from django.utils.functional import curry, cached_property
@@ -241,7 +241,7 @@ class SingleRelatedObjectDescriptor(object):
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)
- params = {'%s__pk__in' % self.related.field.name: instances_dict.keys()}
+ params = {'%s__pk__in' % self.related.field.name: list(instances_dict)}
qs = self.get_query_set(instance=instances[0]).filter(**params)
# Since we're going to assign directly in the cache,
# we must manage the reverse relation cache manually.
@@ -335,9 +335,9 @@ class ReverseSingleRelatedObjectDescriptor(object):
instance_attr = attrgetter(self.field.attname)
instances_dict = dict((instance_attr(inst), inst) for inst in instances)
if other_field.rel:
- params = {'%s__pk__in' % self.field.rel.field_name: instances_dict.keys()}
+ params = {'%s__pk__in' % self.field.rel.field_name: list(instances_dict)}
else:
- params = {'%s__in' % self.field.rel.field_name: instances_dict.keys()}
+ params = {'%s__in' % self.field.rel.field_name: list(instances_dict)}
qs = self.get_query_set(instance=instances[0]).filter(**params)
# Since we're going to assign directly in the cache,
# we must manage the reverse relation cache manually.
@@ -488,7 +488,7 @@ class ForeignRelatedObjectsDescriptor(object):
instance_attr = attrgetter(attname)
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__%s__in' % (rel_field.name, attname): instances_dict.keys()}
+ query = {'%s__%s__in' % (rel_field.name, attname): list(instances_dict)}
qs = super(RelatedManager, self).get_query_set().using(db).filter(**query)
# Since we just bypassed this class' get_query_set(), we must manage
# the reverse relation manually.
@@ -999,7 +999,7 @@ class ForeignKey(RelatedField, Field):
if not self.blank and self.choices:
choice_list = self.get_choices_default()
if len(choice_list) == 2:
- return smart_unicode(choice_list[1][0])
+ return smart_text(choice_list[1][0])
return Field.value_to_string(self, obj)
def contribute_to_class(self, cls, name):
@@ -1205,7 +1205,7 @@ class ManyToManyField(RelatedField, Field):
choices_list = self.get_choices_default()
if len(choices_list) == 1:
data = [choices_list[0][0]]
- return smart_unicode(data)
+ 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
diff --git a/django/db/models/loading.py b/django/db/models/loading.py
index d651584e7a..7a9cb2cb41 100644
--- a/django/db/models/loading.py
+++ b/django/db/models/loading.py
@@ -5,6 +5,7 @@ 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 import six
import imp
import sys
@@ -193,9 +194,9 @@ class AppCache(object):
else:
if only_installed:
app_list = [self.app_models.get(app_label, SortedDict())
- for app_label in self.app_labels.iterkeys()]
+ for app_label in six.iterkeys(self.app_labels)]
else:
- app_list = self.app_models.itervalues()
+ app_list = six.itervalues(self.app_models)
model_list = []
for app in app_list:
model_list.extend(
diff --git a/django/db/models/options.py b/django/db/models/options.py
index 7308a15c6b..2e8ccb49ce 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -8,7 +8,7 @@ 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.translation import activate, deactivate_all, get_language, string_concat
-from django.utils.encoding import force_unicode, smart_str
+from django.utils.encoding import force_text, smart_bytes
from django.utils.datastructures import SortedDict
from django.utils import six
@@ -127,7 +127,7 @@ class Options(object):
if self.parents:
# Promote the first parent link in lieu of adding yet another
# field.
- field = next(self.parents.itervalues())
+ 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
@@ -147,13 +147,13 @@ class Options(object):
# self.duplicate_targets will map each duplicate field column to the
# columns it duplicates.
collections = {}
- for column, target in self.duplicate_targets.iteritems():
+ for column, target in six.iteritems(self.duplicate_targets):
try:
collections[target].add(column)
except KeyError:
collections[target] = set([column])
self.duplicate_targets = {}
- for elt in collections.itervalues():
+ for elt in six.itervalues(collections):
if len(elt) == 1:
continue
for column in elt:
@@ -199,7 +199,7 @@ class Options(object):
return '<Options for %s>' % self.object_name
def __str__(self):
- return "%s.%s" % (smart_str(self.app_label), smart_str(self.module_name))
+ return "%s.%s" % (smart_bytes(self.app_label), smart_bytes(self.module_name))
def verbose_name_raw(self):
"""
@@ -209,7 +209,7 @@ class Options(object):
"""
lang = get_language()
deactivate_all()
- raw = force_unicode(self.verbose_name)
+ raw = force_text(self.verbose_name)
activate(lang)
return raw
verbose_name_raw = property(verbose_name_raw)
@@ -258,7 +258,7 @@ class Options(object):
self._m2m_cache
except AttributeError:
self._fill_m2m_cache()
- return self._m2m_cache.keys()
+ return list(self._m2m_cache)
many_to_many = property(_many_to_many)
def get_m2m_with_model(self):
@@ -269,7 +269,7 @@ class Options(object):
self._m2m_cache
except AttributeError:
self._fill_m2m_cache()
- return self._m2m_cache.items()
+ return list(six.iteritems(self._m2m_cache))
def _fill_m2m_cache(self):
cache = SortedDict()
@@ -326,8 +326,7 @@ class Options(object):
cache = self._name_map
except AttributeError:
cache = self.init_name_map()
- names = cache.keys()
- names.sort()
+ 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('+')]
@@ -417,7 +416,7 @@ class Options(object):
cache = self._fill_related_many_to_many_cache()
if local_only:
return [k for k, v in cache.items() if not v]
- return cache.keys()
+ return list(cache)
def get_all_related_m2m_objects_with_model(self):
"""
@@ -428,7 +427,7 @@ class Options(object):
cache = self._related_many_to_many_cache
except AttributeError:
cache = self._fill_related_many_to_many_cache()
- return cache.items()
+ return list(six.iteritems(cache))
def _fill_related_many_to_many_cache(self):
cache = SortedDict()
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 8b6b42b7b1..e8d6ae2a7b 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -120,7 +120,7 @@ class QuerySet(object):
if len(self._result_cache) <= pos:
self._fill_cache()
- def __nonzero__(self):
+ def __bool__(self):
if self._prefetch_related_lookups and not self._prefetch_done:
# We need all the results in order to be able to do the prefetch
# in one go. To minimize code duplication, we use the __len__
@@ -134,6 +134,7 @@ class QuerySet(object):
except StopIteration:
return False
return True
+ __nonzero__ = __bool__ # Python 2
def __contains__(self, val):
# The 'in' operator works without this method, due to __iter__. This
@@ -245,8 +246,8 @@ class QuerySet(object):
requested = None
max_depth = self.query.max_depth
- extra_select = self.query.extra_select.keys()
- aggregate_select = self.query.aggregate_select.keys()
+ 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:
@@ -593,7 +594,7 @@ class QuerySet(object):
flat = kwargs.pop('flat', False)
if kwargs:
raise TypeError('Unexpected keyword arguments to values_list: %s'
- % (kwargs.keys(),))
+ % (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,
@@ -693,7 +694,7 @@ class QuerySet(object):
depth = kwargs.pop('depth', 0)
if kwargs:
raise TypeError('Unexpected keyword arguments to select_related: %s'
- % (kwargs.keys(),))
+ % (list(kwargs),))
obj = self._clone()
if fields:
if depth:
@@ -751,7 +752,7 @@ class QuerySet(object):
obj = self._clone()
- obj._setup_aggregate_query(kwargs.keys())
+ obj._setup_aggregate_query(list(kwargs))
# Add the aggregates to the query
for (alias, aggregate_expr) in kwargs.items():
@@ -966,9 +967,9 @@ class ValuesQuerySet(QuerySet):
def iterator(self):
# Purge any extra columns that haven't been explicitly asked for
- extra_names = self.query.extra_select.keys()
+ extra_names = list(self.query.extra_select)
field_names = self.field_names
- aggregate_names = self.query.aggregate_select.keys()
+ aggregate_names = list(self.query.aggregate_select)
names = extra_names + field_names + aggregate_names
@@ -1097,9 +1098,9 @@ class ValuesListQuerySet(ValuesQuerySet):
# 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 = self.query.extra_select.keys()
+ extra_names = list(self.query.extra_select)
field_names = self.field_names
- aggregate_names = self.query.aggregate_select.keys()
+ aggregate_names = list(self.query.aggregate_select)
names = extra_names + field_names + aggregate_names
@@ -1527,7 +1528,7 @@ class RawQuerySet(object):
# Associate fields to values
if skip:
model_init_kwargs = {}
- for attname, pos in model_init_field_names.iteritems():
+ for attname, pos in six.iteritems(model_init_field_names):
model_init_kwargs[attname] = values[pos]
instance = model_cls(**model_init_kwargs)
else:
diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
index 60bdb2bcb4..c1a690a524 100644
--- a/django/db/models/query_utils.py
+++ b/django/db/models/query_utils.py
@@ -8,6 +8,7 @@ circular import difficulties.
from __future__ import unicode_literals
from django.db.backends import util
+from django.utils import six
from django.utils import tree
@@ -40,7 +41,7 @@ class Q(tree.Node):
default = AND
def __init__(self, *args, **kwargs):
- super(Q, self).__init__(children=list(args) + kwargs.items())
+ super(Q, self).__init__(children=list(args) + list(six.iteritems(kwargs)))
def _combine(self, other, conn):
if not isinstance(other, Q):
@@ -114,7 +115,7 @@ class DeferredAttribute(object):
def _check_parent_chain(self, instance, name):
"""
- Check if the field value can be fetched from a parent field already
+ 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.
"""
diff --git a/django/db/models/related.py b/django/db/models/related.py
index 90995d749f..a0dcec7132 100644
--- a/django/db/models/related.py
+++ b/django/db/models/related.py
@@ -1,4 +1,4 @@
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import smart_text
from django.db.models.fields import BLANK_CHOICE_DASH
class BoundRelatedObject(object):
@@ -34,9 +34,9 @@ class RelatedObject(object):
if limit_to_currently_related:
queryset = queryset.complex_filter(
{'%s__isnull' % self.parent_model._meta.module_name: False})
- lst = [(x._get_pk_val(), smart_unicode(x)) for x in queryset]
+ 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,
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 7a0afa349d..1311ea546c 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -9,6 +9,7 @@ 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.utils import DatabaseError
+from django.utils import six
class SQLCompiler(object):
@@ -82,7 +83,7 @@ class SQLCompiler(object):
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)
params = []
- for val in self.query.extra_select.itervalues():
+ for val in six.itervalues(self.query.extra_select):
params.extend(val[1])
result = ['SELECT']
@@ -177,7 +178,7 @@ class SQLCompiler(object):
"""
qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
- result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in self.query.extra_select.iteritems()]
+ result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in six.iteritems(self.query.extra_select)]
aliases = set(self.query.extra_select.keys())
if with_aliases:
col_aliases = aliases.copy()
@@ -553,7 +554,7 @@ class SQLCompiler(object):
group_by = self.query.group_by or []
extra_selects = []
- for extra_select, extra_params in self.query.extra_select.itervalues():
+ for extra_select, extra_params in six.itervalues(self.query.extra_select):
extra_selects.append(extra_select)
params.extend(extra_params)
cols = (group_by + self.query.select +
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 53dad608bf..be257a5410 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -10,8 +10,9 @@ 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_unicode
+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 import signals
from django.db.models.expressions import ExpressionNode
@@ -602,22 +603,22 @@ class Query(object):
# slight complexity here is handling fields that exist on parent
# models.
workset = {}
- for model, values in seen.iteritems():
+ 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 must_include.iteritems():
+ 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 workset.iteritems():
+ for model, values in six.iteritems(workset):
callback(target, model, values)
else:
- for model, values in must_include.iteritems():
+ for model, values in six.iteritems(must_include):
if model in seen:
seen[model].update(values)
else:
@@ -631,7 +632,7 @@ class Query(object):
for model in orig_opts.get_parent_list():
if model not in seen:
seen[model] = set()
- for model, values in seen.iteritems():
+ for model, values in six.iteritems(seen):
callback(target, model, values)
@@ -770,7 +771,7 @@ class Query(object):
for k, aliases in self.join_map.items():
aliases = tuple([change_map.get(a, a) for a in aliases])
self.join_map[k] = aliases
- for old_alias, new_alias in change_map.iteritems():
+ 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]
@@ -792,7 +793,7 @@ class Query(object):
self.included_inherited_models[key] = change_map[alias]
# 3. Update any joins that refer to the old alias.
- for alias, data in self.alias_map.iteritems():
+ 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])
@@ -842,7 +843,7 @@ class Query(object):
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.itervalues() if count])
+ return len([1 for count in six.itervalues(self.alias_refcount) if count])
def join(self, connection, always_create=False, exclusions=(),
promote=False, outer_if_first=False, nullable=False, reuse=None):
@@ -1302,7 +1303,7 @@ class Query(object):
field, model, direct, m2m = opts.get_field_by_name(f.name)
break
else:
- names = opts.get_all_field_names() + self.aggregate_select.keys()
+ names = opts.get_all_field_names() + list(self.aggregate_select)
raise FieldError("Cannot resolve keyword %r into field. "
"Choices are: %s" % (name, ", ".join(names)))
@@ -1571,7 +1572,7 @@ class Query(object):
# Tag.objects.exclude(parent__parent__name='t1'), a tag with no parent
# would otherwise be overlooked).
active_positions = [pos for (pos, count) in
- enumerate(query.alias_refcount.itervalues()) if count]
+ enumerate(six.itervalues(query.alias_refcount)) if count]
if active_positions[-1] > 1:
self.add_filter(('%s__isnull' % prefix, False), negate=True,
trim=True, can_reuse=can_reuse)
@@ -1660,8 +1661,8 @@ class Query(object):
# from the model on which the lookup failed.
raise
else:
- names = sorted(opts.get_all_field_names() + self.extra.keys()
- + self.aggregate_select.keys())
+ 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()
@@ -1775,7 +1776,7 @@ class Query(object):
else:
param_iter = iter([])
for name, entry in select.items():
- entry = force_unicode(entry)
+ entry = force_text(entry)
entry_params = []
pos = entry.find("%s")
while pos != -1:
diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py
index 7b92394e90..937505b9b0 100644
--- a/django/db/models/sql/subqueries.py
+++ b/django/db/models/sql/subqueries.py
@@ -10,7 +10,8 @@ from django.db.models.sql.query import Query
from django.db.models.sql.where import AND, Constraint
from django.utils.datastructures import SortedDict
from django.utils.functional import Promise
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
+from django.utils import six
__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
@@ -87,7 +88,7 @@ class UpdateQuery(Query):
querysets.
"""
values_seq = []
- for name, val in values.iteritems():
+ for name, val in six.iteritems(values):
field, model, direct, m2m = self.model._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)
@@ -104,7 +105,7 @@ class UpdateQuery(Query):
saving models.
"""
# Check that no Promise object passes to the query. Refs #10498.
- values_seq = [(value[0], value[1], force_unicode(value[2]))
+ 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)
@@ -129,7 +130,7 @@ class UpdateQuery(Query):
if not self.related_updates:
return []
result = []
- for model, values in self.related_updates.iteritems():
+ for model, values in six.iteritems(self.related_updates):
query = UpdateQuery(model)
query.values = values
if self.related_ids is not None:
@@ -170,7 +171,7 @@ class InsertQuery(Query):
for obj in objs:
value = getattr(obj, field.attname)
if isinstance(value, Promise):
- setattr(obj, field.attname, force_unicode(value))
+ setattr(obj, field.attname, force_text(value))
self.objs = objs
self.raw = raw