mirror of
				https://github.com/django/django.git
				synced 2025-10-26 07:06:08 +00:00 
			
		
		
		
	Deprecated SortedDict (replaced with collections.OrderedDict)
Thanks Loic Bistuer for the review.
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							b278f7478d
						
					
				
				
					commit
					07876cf02b
				
			| @@ -1,3 +1,4 @@ | ||||
| from collections import OrderedDict | ||||
| import copy | ||||
| import operator | ||||
| from functools import partial, reduce, update_wrapper | ||||
| @@ -29,7 +30,6 @@ from django.http.response import HttpResponseBase | ||||
| from django.shortcuts import get_object_or_404 | ||||
| from django.template.response import SimpleTemplateResponse, TemplateResponse | ||||
| from django.utils.decorators import method_decorator | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.html import escape, escapejs | ||||
| from django.utils.safestring import mark_safe | ||||
| from django.utils import six | ||||
| @@ -672,7 +672,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         # want *any* actions enabled on this page. | ||||
|         from django.contrib.admin.views.main import _is_changelist_popup | ||||
|         if self.actions is None or _is_changelist_popup(request): | ||||
|             return SortedDict() | ||||
|             return OrderedDict() | ||||
|  | ||||
|         actions = [] | ||||
|  | ||||
| @@ -693,8 +693,8 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         # get_action might have returned None, so filter any of those out. | ||||
|         actions = filter(None, actions) | ||||
|  | ||||
|         # Convert the actions into a SortedDict keyed by name. | ||||
|         actions = SortedDict([ | ||||
|         # Convert the actions into an OrderedDict keyed by name. | ||||
|         actions = OrderedDict([ | ||||
|             (name, (func, name, desc)) | ||||
|             for func, name, desc in actions | ||||
|         ]) | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| from collections import OrderedDict | ||||
| import sys | ||||
| import warnings | ||||
|  | ||||
| @@ -7,7 +8,6 @@ from django.core.urlresolvers import reverse | ||||
| from django.db import models | ||||
| from django.db.models.fields import FieldDoesNotExist | ||||
| from django.utils import six | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.deprecation import RenameMethodsBase | ||||
| from django.utils.encoding import force_str, force_text | ||||
| from django.utils.translation import ugettext, ugettext_lazy | ||||
| @@ -319,13 +319,13 @@ class ChangeList(six.with_metaclass(RenameChangeListMethods)): | ||||
|  | ||||
|     def get_ordering_field_columns(self): | ||||
|         """ | ||||
|         Returns a SortedDict of ordering field column numbers and asc/desc | ||||
|         Returns an OrderedDict of ordering field column numbers and asc/desc | ||||
|         """ | ||||
|  | ||||
|         # We must cope with more than one column having the same underlying sort | ||||
|         # field, so we base things on column numbers. | ||||
|         ordering = self._get_default_ordering() | ||||
|         ordering_fields = SortedDict() | ||||
|         ordering_fields = OrderedDict() | ||||
|         if ORDER_VAR not in self.params: | ||||
|             # for ordering specified on ModelAdmin or model Meta, we don't know | ||||
|             # the right column numbers absolutely, because there might be more | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from collections import OrderedDict | ||||
|  | ||||
| from django import forms | ||||
| from django.forms.util import flatatt | ||||
| from django.template import loader | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.encoding import force_bytes | ||||
| from django.utils.html import format_html, format_html_join | ||||
| from django.utils.http import urlsafe_base64_encode | ||||
| @@ -324,7 +325,7 @@ class PasswordChangeForm(SetPasswordForm): | ||||
|             ) | ||||
|         return old_password | ||||
|  | ||||
| PasswordChangeForm.base_fields = SortedDict([ | ||||
| PasswordChangeForm.base_fields = OrderedDict([ | ||||
|     (k, PasswordChangeForm.base_fields[k]) | ||||
|     for k in ['old_password', 'new_password1', 'new_password2'] | ||||
| ]) | ||||
|   | ||||
| @@ -2,13 +2,13 @@ from __future__ import unicode_literals | ||||
|  | ||||
| import base64 | ||||
| import binascii | ||||
| from collections import OrderedDict | ||||
| import hashlib | ||||
| import importlib | ||||
|  | ||||
| from django.dispatch import receiver | ||||
| from django.conf import settings | ||||
| from django.test.signals import setting_changed | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.encoding import force_bytes, force_str, force_text | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.utils.crypto import ( | ||||
| @@ -243,7 +243,7 @@ class PBKDF2PasswordHasher(BasePasswordHasher): | ||||
|     def safe_summary(self, encoded): | ||||
|         algorithm, iterations, salt, hash = encoded.split('$', 3) | ||||
|         assert algorithm == self.algorithm | ||||
|         return SortedDict([ | ||||
|         return OrderedDict([ | ||||
|             (_('algorithm'), algorithm), | ||||
|             (_('iterations'), iterations), | ||||
|             (_('salt'), mask_hash(salt)), | ||||
| @@ -320,7 +320,7 @@ class BCryptSHA256PasswordHasher(BasePasswordHasher): | ||||
|         algorithm, empty, algostr, work_factor, data = encoded.split('$', 4) | ||||
|         assert algorithm == self.algorithm | ||||
|         salt, checksum = data[:22], data[22:] | ||||
|         return SortedDict([ | ||||
|         return OrderedDict([ | ||||
|             (_('algorithm'), algorithm), | ||||
|             (_('work factor'), work_factor), | ||||
|             (_('salt'), mask_hash(salt)), | ||||
| @@ -368,7 +368,7 @@ class SHA1PasswordHasher(BasePasswordHasher): | ||||
|     def safe_summary(self, encoded): | ||||
|         algorithm, salt, hash = encoded.split('$', 2) | ||||
|         assert algorithm == self.algorithm | ||||
|         return SortedDict([ | ||||
|         return OrderedDict([ | ||||
|             (_('algorithm'), algorithm), | ||||
|             (_('salt'), mask_hash(salt, show=2)), | ||||
|             (_('hash'), mask_hash(hash)), | ||||
| @@ -396,7 +396,7 @@ class MD5PasswordHasher(BasePasswordHasher): | ||||
|     def safe_summary(self, encoded): | ||||
|         algorithm, salt, hash = encoded.split('$', 2) | ||||
|         assert algorithm == self.algorithm | ||||
|         return SortedDict([ | ||||
|         return OrderedDict([ | ||||
|             (_('algorithm'), algorithm), | ||||
|             (_('salt'), mask_hash(salt, show=2)), | ||||
|             (_('hash'), mask_hash(hash)), | ||||
| @@ -429,7 +429,7 @@ class UnsaltedSHA1PasswordHasher(BasePasswordHasher): | ||||
|     def safe_summary(self, encoded): | ||||
|         assert encoded.startswith('sha1$$') | ||||
|         hash = encoded[6:] | ||||
|         return SortedDict([ | ||||
|         return OrderedDict([ | ||||
|             (_('algorithm'), self.algorithm), | ||||
|             (_('hash'), mask_hash(hash)), | ||||
|         ]) | ||||
| @@ -462,7 +462,7 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher): | ||||
|         return constant_time_compare(encoded, encoded_2) | ||||
|  | ||||
|     def safe_summary(self, encoded): | ||||
|         return SortedDict([ | ||||
|         return OrderedDict([ | ||||
|             (_('algorithm'), self.algorithm), | ||||
|             (_('hash'), mask_hash(encoded, show=3)), | ||||
|         ]) | ||||
| @@ -496,7 +496,7 @@ class CryptPasswordHasher(BasePasswordHasher): | ||||
|     def safe_summary(self, encoded): | ||||
|         algorithm, salt, data = encoded.split('$', 2) | ||||
|         assert algorithm == self.algorithm | ||||
|         return SortedDict([ | ||||
|         return OrderedDict([ | ||||
|             (_('algorithm'), algorithm), | ||||
|             (_('salt'), salt), | ||||
|             (_('hash'), mask_hash(data, show=3)), | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| from collections import OrderedDict | ||||
| import re | ||||
|  | ||||
| from django import forms | ||||
| @@ -5,7 +6,6 @@ from django.shortcuts import redirect | ||||
| from django.core.urlresolvers import reverse | ||||
| from django.forms import formsets, ValidationError | ||||
| from django.views.generic import TemplateView | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.decorators import classonlymethod | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.utils import six | ||||
| @@ -158,7 +158,7 @@ class WizardView(TemplateView): | ||||
|         form_list = form_list or kwargs.pop('form_list', | ||||
|             getattr(cls, 'form_list', None)) or [] | ||||
|  | ||||
|         computed_form_list = SortedDict() | ||||
|         computed_form_list = OrderedDict() | ||||
|  | ||||
|         assert len(form_list) > 0, 'at least one form is needed' | ||||
|  | ||||
| @@ -206,7 +206,7 @@ class WizardView(TemplateView): | ||||
|         The form_list is always generated on the fly because condition methods | ||||
|         could use data from other (maybe previous forms). | ||||
|         """ | ||||
|         form_list = SortedDict() | ||||
|         form_list = OrderedDict() | ||||
|         for form_key, form_class in six.iteritems(self.form_list): | ||||
|             # try to fetch the value from condition list, by default, the form | ||||
|             # gets passed to the new list. | ||||
| @@ -498,9 +498,10 @@ class WizardView(TemplateView): | ||||
|         if step is None: | ||||
|             step = self.steps.current | ||||
|         form_list = self.get_form_list() | ||||
|         key = form_list.keyOrder.index(step) + 1 | ||||
|         if len(form_list.keyOrder) > key: | ||||
|             return form_list.keyOrder[key] | ||||
|         keys = list(form_list.keys()) | ||||
|         key = keys.index(step) + 1 | ||||
|         if len(keys) > key: | ||||
|             return keys[key] | ||||
|         return None | ||||
|  | ||||
|     def get_prev_step(self, step=None): | ||||
| @@ -512,9 +513,10 @@ class WizardView(TemplateView): | ||||
|         if step is None: | ||||
|             step = self.steps.current | ||||
|         form_list = self.get_form_list() | ||||
|         key = form_list.keyOrder.index(step) - 1 | ||||
|         keys = list(form_list.keys()) | ||||
|         key = keys.index(step) - 1 | ||||
|         if key >= 0: | ||||
|             return form_list.keyOrder[key] | ||||
|             return keys[key] | ||||
|         return None | ||||
|  | ||||
|     def get_step_index(self, step=None): | ||||
| @@ -524,7 +526,7 @@ class WizardView(TemplateView): | ||||
|         """ | ||||
|         if step is None: | ||||
|             step = self.steps.current | ||||
|         return self.get_form_list().keyOrder.index(step) | ||||
|         return list(self.get_form_list().keys()).index(step) | ||||
|  | ||||
|     def get_context_data(self, form, **kwargs): | ||||
|         """ | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| from collections import OrderedDict | ||||
| import os | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.core.files.storage import default_storage, Storage, FileSystemStorage | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.functional import empty, memoize, LazyObject | ||||
| from django.utils.module_loading import import_by_path | ||||
| from django.utils._os import safe_join | ||||
| @@ -11,7 +12,7 @@ from django.utils import six | ||||
| from django.contrib.staticfiles import utils | ||||
| from django.contrib.staticfiles.storage import AppStaticStorage | ||||
|  | ||||
| _finders = SortedDict() | ||||
| _finders = OrderedDict() | ||||
|  | ||||
|  | ||||
| class BaseFinder(object): | ||||
| @@ -47,7 +48,7 @@ class FileSystemFinder(BaseFinder): | ||||
|         # List of locations with static files | ||||
|         self.locations = [] | ||||
|         # Maps dir paths to an appropriate storage instance | ||||
|         self.storages = SortedDict() | ||||
|         self.storages = OrderedDict() | ||||
|         if not isinstance(settings.STATICFILES_DIRS, (list, tuple)): | ||||
|             raise ImproperlyConfigured( | ||||
|                 "Your STATICFILES_DIRS setting is not a tuple or list; " | ||||
| @@ -118,7 +119,7 @@ class AppDirectoriesFinder(BaseFinder): | ||||
|         # The list of apps that are handled | ||||
|         self.apps = [] | ||||
|         # Mapping of app module paths to storage instances | ||||
|         self.storages = SortedDict() | ||||
|         self.storages = OrderedDict() | ||||
|         if apps is None: | ||||
|             apps = settings.INSTALLED_APPS | ||||
|         for app in apps: | ||||
|   | ||||
| @@ -2,12 +2,12 @@ from __future__ import unicode_literals | ||||
|  | ||||
| import os | ||||
| import sys | ||||
| from collections import OrderedDict | ||||
| from optparse import make_option | ||||
|  | ||||
| from django.core.files.storage import FileSystemStorage | ||||
| from django.core.management.base import CommandError, NoArgsCommand | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.six.moves import input | ||||
|  | ||||
| from django.contrib.staticfiles import finders, storage | ||||
| @@ -97,7 +97,7 @@ class Command(NoArgsCommand): | ||||
|         else: | ||||
|             handler = self.copy_file | ||||
|  | ||||
|         found_files = SortedDict() | ||||
|         found_files = OrderedDict() | ||||
|         for finder in finders.get_finders(): | ||||
|             for path, storage in finder.list(self.ignore_patterns): | ||||
|                 # Prefix the relative path if the source storage contains it | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| from __future__ import unicode_literals | ||||
| from collections import OrderedDict | ||||
| import hashlib | ||||
| from importlib import import_module | ||||
| import os | ||||
| @@ -16,7 +17,6 @@ from django.core.cache import (get_cache, InvalidCacheBackendError, | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.core.files.base import ContentFile | ||||
| from django.core.files.storage import FileSystemStorage, get_storage_class | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.encoding import force_bytes, force_text | ||||
| from django.utils.functional import LazyObject | ||||
| from django.utils._os import upath | ||||
| @@ -64,7 +64,7 @@ class CachedFilesMixin(object): | ||||
|         except InvalidCacheBackendError: | ||||
|             # Use the default backend | ||||
|             self.cache = default_cache | ||||
|         self._patterns = SortedDict() | ||||
|         self._patterns = OrderedDict() | ||||
|         for extension, patterns in self.patterns: | ||||
|             for pattern in patterns: | ||||
|                 if isinstance(pattern, (tuple, list)): | ||||
| @@ -202,7 +202,7 @@ class CachedFilesMixin(object): | ||||
|  | ||||
|     def post_process(self, paths, dry_run=False, **options): | ||||
|         """ | ||||
|         Post process the given SortedDict of files (called from collectstatic). | ||||
|         Post process the given OrderedDict of files (called from collectstatic). | ||||
|  | ||||
|         Processing is actually two separate operations: | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,11 @@ | ||||
| from collections import OrderedDict | ||||
| from optparse import make_option | ||||
|  | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.core.management.base import BaseCommand, CommandError | ||||
| from django.core import serializers | ||||
| from django.db import router, DEFAULT_DB_ALIAS | ||||
| from django.utils.datastructures import SortedDict | ||||
|  | ||||
| from optparse import make_option | ||||
|  | ||||
| class Command(BaseCommand): | ||||
|     option_list = BaseCommand.option_list + ( | ||||
| @@ -66,11 +67,11 @@ class Command(BaseCommand): | ||||
|         if len(app_labels) == 0: | ||||
|             if primary_keys: | ||||
|                 raise CommandError("You can only use --pks option with one model") | ||||
|             app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps) | ||||
|             app_list = OrderedDict((app, None) for app in get_apps() if app not in excluded_apps) | ||||
|         else: | ||||
|             if len(app_labels) > 1 and primary_keys: | ||||
|                 raise CommandError("You can only use --pks option with one model") | ||||
|             app_list = SortedDict() | ||||
|             app_list = OrderedDict() | ||||
|             for label in app_labels: | ||||
|                 try: | ||||
|                     app_label, model_label = label.split('.') | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from collections import OrderedDict | ||||
| import keyword | ||||
| import re | ||||
| from optparse import make_option | ||||
|  | ||||
| from django.core.management.base import NoArgsCommand, CommandError | ||||
| from django.db import connections, DEFAULT_DB_ALIAS | ||||
| from django.utils.datastructures import SortedDict | ||||
|  | ||||
|  | ||||
| class Command(NoArgsCommand): | ||||
| @@ -69,7 +69,7 @@ class Command(NoArgsCommand): | ||||
|             used_column_names = [] # Holds column names used in the table so far | ||||
|             for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)): | ||||
|                 comment_notes = [] # Holds Field notes, to be displayed in a Python comment. | ||||
|                 extra_params = SortedDict()  # Holds Field parameters such as 'db_column'. | ||||
|                 extra_params = OrderedDict()  # Holds Field parameters such as 'db_column'. | ||||
|                 column_name = row[0] | ||||
|                 is_relation = i in relations | ||||
|  | ||||
| @@ -193,7 +193,7 @@ class Command(NoArgsCommand): | ||||
|         description, this routine will return the given field type name, as | ||||
|         well as any additional keyword parameters and notes for the field. | ||||
|         """ | ||||
|         field_params = SortedDict() | ||||
|         field_params = OrderedDict() | ||||
|         field_notes = [] | ||||
|  | ||||
|         try: | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| from collections import OrderedDict | ||||
| from importlib import import_module | ||||
| from optparse import make_option | ||||
| import itertools | ||||
| @@ -9,7 +10,6 @@ from django.core.management.base import NoArgsCommand | ||||
| from django.core.management.color import no_style | ||||
| from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal, emit_pre_sync_signal | ||||
| from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS | ||||
| from django.utils.datastructures import SortedDict | ||||
|  | ||||
|  | ||||
| class Command(NoArgsCommand): | ||||
| @@ -76,7 +76,7 @@ class Command(NoArgsCommand): | ||||
|             return not ((converter(opts.db_table) in tables) or | ||||
|                 (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)) | ||||
|  | ||||
|         manifest = SortedDict( | ||||
|         manifest = OrderedDict( | ||||
|             (app_name, list(filter(model_installed, model_list))) | ||||
|             for app_name, model_list in all_models | ||||
|         ) | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| from collections import OrderedDict | ||||
| 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 | ||||
|  | ||||
|  | ||||
| @@ -234,7 +234,7 @@ class Collector(object): | ||||
|                     found = True | ||||
|             if not found: | ||||
|                 return | ||||
|         self.data = SortedDict([(model, self.data[model]) | ||||
|         self.data = OrderedDict([(model, self.data[model]) | ||||
|                                 for model in sorted_models]) | ||||
|  | ||||
|     def delete(self): | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| "Utilities for loading models and the modules that contain them." | ||||
|  | ||||
| from collections import OrderedDict | ||||
| import copy | ||||
| import imp | ||||
| from importlib import import_module | ||||
| import os | ||||
| @@ -7,7 +9,6 @@ import sys | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.module_loading import module_has_submodule | ||||
| from django.utils._os import upath | ||||
| from django.utils import six | ||||
| @@ -17,6 +18,14 @@ __all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models', | ||||
|  | ||||
| MODELS_MODULE_NAME = 'models' | ||||
|  | ||||
| class ModelDict(OrderedDict): | ||||
|     """ | ||||
|     We need to special-case the deepcopy for this, as the keys are modules, | ||||
|     which can't be deep copied. | ||||
|     """ | ||||
|     def __deepcopy__(self, memo): | ||||
|         return self.__class__([(key, copy.deepcopy(value, memo)) | ||||
|                                for key, value in self.items()]) | ||||
|  | ||||
| class UnavailableApp(Exception): | ||||
|     pass | ||||
| @@ -31,14 +40,14 @@ class AppCache(object): | ||||
|     # 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(), | ||||
|         app_store=ModelDict(), | ||||
|  | ||||
|         # 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(), | ||||
|         app_models=ModelDict(), | ||||
|  | ||||
|         # Mapping of app_labels to errors raised when trying to import the app. | ||||
|         app_errors={}, | ||||
| @@ -244,12 +253,12 @@ class AppCache(object): | ||||
|         if app_mod: | ||||
|             if app_mod in self.app_store: | ||||
|                 app_list = [self.app_models.get(self._label_for(app_mod), | ||||
|                                                 SortedDict())] | ||||
|                                                 ModelDict())] | ||||
|             else: | ||||
|                 app_list = [] | ||||
|         else: | ||||
|             if only_installed: | ||||
|                 app_list = [self.app_models.get(app_label, SortedDict()) | ||||
|                 app_list = [self.app_models.get(app_label, ModelDict()) | ||||
|                             for app_label in six.iterkeys(self.app_labels)] | ||||
|             else: | ||||
|                 app_list = six.itervalues(self.app_models) | ||||
| @@ -298,7 +307,7 @@ class AppCache(object): | ||||
|             # 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()) | ||||
|             model_dict = self.app_models.setdefault(app_label, ModelDict()) | ||||
|             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 | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from collections import OrderedDict | ||||
| import re | ||||
| from bisect import bisect | ||||
| import warnings | ||||
| @@ -11,7 +12,6 @@ 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 | ||||
|  | ||||
| @@ -58,7 +58,7 @@ class Options(object): | ||||
|         # concrete models, the concrete_model is always the class itself. | ||||
|         self.concrete_model = None | ||||
|         self.swappable = None | ||||
|         self.parents = SortedDict() | ||||
|         self.parents = OrderedDict() | ||||
|         self.auto_created = False | ||||
|  | ||||
|         # To handle various inheritance situations, we need to track where | ||||
| @@ -332,7 +332,7 @@ class Options(object): | ||||
|         return list(six.iteritems(self._m2m_cache)) | ||||
|  | ||||
|     def _fill_m2m_cache(self): | ||||
|         cache = SortedDict() | ||||
|         cache = OrderedDict() | ||||
|         for parent in self.parents: | ||||
|             for field, model in parent._meta.get_m2m_with_model(): | ||||
|                 if model: | ||||
| @@ -474,7 +474,7 @@ class Options(object): | ||||
|         return [t for t in cache.items() if all(p(*t) for p in predicates)] | ||||
|  | ||||
|     def _fill_related_objects_cache(self): | ||||
|         cache = SortedDict() | ||||
|         cache = OrderedDict() | ||||
|         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): | ||||
| @@ -519,7 +519,7 @@ class Options(object): | ||||
|         return list(six.iteritems(cache)) | ||||
|  | ||||
|     def _fill_related_many_to_many_cache(self): | ||||
|         cache = SortedDict() | ||||
|         cache = OrderedDict() | ||||
|         parent_list = self.get_parent_list() | ||||
|         for parent in self.parents: | ||||
|             for obj, model in parent._meta.get_all_related_m2m_objects_with_model(): | ||||
|   | ||||
| @@ -7,9 +7,9 @@ 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. | ||||
| """ | ||||
|  | ||||
| from collections import OrderedDict | ||||
| 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 | ||||
| @@ -142,7 +142,7 @@ class Query(object): | ||||
|         self.select_related = False | ||||
|  | ||||
|         # SQL aggregate-related attributes | ||||
|         self.aggregates = SortedDict() # Maps alias -> SQL aggregate function | ||||
|         self.aggregates = OrderedDict() # Maps alias -> SQL aggregate function | ||||
|         self.aggregate_select_mask = None | ||||
|         self._aggregate_select_cache = None | ||||
|  | ||||
| @@ -152,7 +152,7 @@ class Query(object): | ||||
|  | ||||
|         # 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 = OrderedDict()  # Maps col_alias -> (col_sql, params). | ||||
|         self.extra_select_mask = None | ||||
|         self._extra_select_cache = None | ||||
|  | ||||
| @@ -741,7 +741,7 @@ class Query(object): | ||||
|             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( | ||||
|         self.aggregates = OrderedDict( | ||||
|             (key, relabel_column(col)) for key, col in self.aggregates.items()) | ||||
|  | ||||
|         # 2. Rename the alias in the internal table/alias datastructures. | ||||
| @@ -795,7 +795,7 @@ class Query(object): | ||||
|         assert current < ord('Z') | ||||
|         prefix = chr(current + 1) | ||||
|         self.alias_prefix = prefix | ||||
|         change_map = SortedDict() | ||||
|         change_map = OrderedDict() | ||||
|         for pos, alias in enumerate(self.tables): | ||||
|             if alias in exceptions: | ||||
|                 continue | ||||
| @@ -1638,7 +1638,7 @@ class Query(object): | ||||
|             # dictionary with their parameters in 'select_params' so that | ||||
|             # subsequent updates to the select dictionary also adjust the | ||||
|             # parameters appropriately. | ||||
|             select_pairs = SortedDict() | ||||
|             select_pairs = OrderedDict() | ||||
|             if select_params: | ||||
|                 param_iter = iter(select_params) | ||||
|             else: | ||||
| @@ -1651,7 +1651,7 @@ class Query(object): | ||||
|                     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. | ||||
|             # This is order preserving, since self.extra_select is an OrderedDict. | ||||
|             self.extra.update(select_pairs) | ||||
|         if where or params: | ||||
|             self.where.add(ExtraWhere(where, params), AND) | ||||
| @@ -1760,7 +1760,7 @@ class Query(object): | ||||
|         self._extra_select_cache = None | ||||
|  | ||||
|     def _aggregate_select(self): | ||||
|         """The SortedDict of aggregate columns that are not masked, and should | ||||
|         """The OrderedDict of aggregate columns that are not masked, and should | ||||
|         be used in the SELECT clause. | ||||
|  | ||||
|         This result is cached for optimization purposes. | ||||
| @@ -1768,7 +1768,7 @@ class Query(object): | ||||
|         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([ | ||||
|             self._aggregate_select_cache = OrderedDict([ | ||||
|                 (k, v) for k, v in self.aggregates.items() | ||||
|                 if k in self.aggregate_select_mask | ||||
|             ]) | ||||
| @@ -1781,7 +1781,7 @@ class Query(object): | ||||
|         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([ | ||||
|             self._extra_select_cache = OrderedDict([ | ||||
|                 (k, v) for k, v in self.extra.items() | ||||
|                 if k in self.extra_select_mask | ||||
|             ]) | ||||
|   | ||||
| @@ -4,6 +4,7 @@ Form classes | ||||
|  | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from collections import OrderedDict | ||||
| import copy | ||||
| import warnings | ||||
|  | ||||
| @@ -11,7 +12,6 @@ from django.core.exceptions import ValidationError | ||||
| from django.forms.fields import Field, FileField | ||||
| from django.forms.util import flatatt, ErrorDict, ErrorList | ||||
| from django.forms.widgets import Media, media_property, TextInput, Textarea | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.html import conditional_escape, format_html | ||||
| from django.utils.encoding import smart_text, force_text, python_2_unicode_compatible | ||||
| from django.utils.safestring import mark_safe | ||||
| @@ -55,7 +55,7 @@ def get_declared_fields(bases, attrs, with_base_fields=True): | ||||
|             if hasattr(base, 'declared_fields'): | ||||
|                 fields = list(six.iteritems(base.declared_fields)) + fields | ||||
|  | ||||
|     return SortedDict(fields) | ||||
|     return OrderedDict(fields) | ||||
|  | ||||
| class DeclarativeFieldsMetaclass(type): | ||||
|     """ | ||||
|   | ||||
| @@ -5,6 +5,7 @@ and database field objects. | ||||
|  | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from collections import OrderedDict | ||||
| import warnings | ||||
|  | ||||
| from django.core.exceptions import ValidationError, NON_FIELD_ERRORS, FieldError | ||||
| @@ -15,7 +16,6 @@ from django.forms.util import ErrorList | ||||
| from django.forms.widgets import (SelectMultiple, HiddenInput, | ||||
|     MultipleHiddenInput, media_property, CheckboxSelectMultiple) | ||||
| from django.utils.encoding import smart_text, force_text | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils import six | ||||
| from django.utils.text import get_text_list, capfirst | ||||
| from django.utils.translation import ugettext_lazy as _, ugettext, string_concat | ||||
| @@ -142,7 +142,7 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None, | ||||
|                      formfield_callback=None, localized_fields=None, | ||||
|                      labels=None, help_texts=None, error_messages=None): | ||||
|     """ | ||||
|     Returns a ``SortedDict`` containing form fields for the given model. | ||||
|     Returns a ``OrderedDict`` containing form fields for the given model. | ||||
|  | ||||
|     ``fields`` is an optional list of field names. If provided, only the named | ||||
|     fields will be included in the returned fields. | ||||
| @@ -199,9 +199,9 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None, | ||||
|             field_list.append((f.name, formfield)) | ||||
|         else: | ||||
|             ignored.append(f.name) | ||||
|     field_dict = SortedDict(field_list) | ||||
|     field_dict = OrderedDict(field_list) | ||||
|     if fields: | ||||
|         field_dict = SortedDict( | ||||
|         field_dict = OrderedDict( | ||||
|             [(f, field_dict.get(f)) for f in fields | ||||
|                 if ((not exclude) or (exclude and f not in exclude)) and (f not in ignored)] | ||||
|         ) | ||||
|   | ||||
| @@ -1,12 +1,13 @@ | ||||
| "This is the locale selecting middleware that will look at accept headers" | ||||
|  | ||||
| from collections import OrderedDict | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.core.urlresolvers import (is_valid_path, get_resolver, | ||||
|                                       LocaleRegexURLResolver) | ||||
| from django.http import HttpResponseRedirect | ||||
| from django.utils.cache import patch_vary_headers | ||||
| from django.utils import translation | ||||
| from django.utils.datastructures import SortedDict | ||||
|  | ||||
|  | ||||
| class LocaleMiddleware(object): | ||||
| @@ -19,7 +20,7 @@ class LocaleMiddleware(object): | ||||
|     """ | ||||
|  | ||||
|     def __init__(self): | ||||
|         self._supported_languages = SortedDict(settings.LANGUAGES) | ||||
|         self._supported_languages = OrderedDict(settings.LANGUAGES) | ||||
|         self._is_language_prefix_patterns_used = False | ||||
|         for url_pattern in get_resolver(None).url_patterns: | ||||
|             if isinstance(url_pattern, LocaleRegexURLResolver): | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import copy | ||||
| import warnings | ||||
| from django.utils import six | ||||
|  | ||||
|  | ||||
| class MergeDict(object): | ||||
|     """ | ||||
|     A simple class for creating new "virtual" dictionaries that actually look | ||||
| @@ -124,6 +124,10 @@ class SortedDict(dict): | ||||
|         return instance | ||||
|  | ||||
|     def __init__(self, data=None): | ||||
|         warnings.warn( | ||||
|             "SortedDict is deprecated and will be removed in Django 1.9.", | ||||
|             PendingDeprecationWarning, stacklevel=2 | ||||
|         ) | ||||
|         if data is None or isinstance(data, dict): | ||||
|             data = data or [] | ||||
|             super(SortedDict, self).__init__(data) | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| """Translation helper functions.""" | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from collections import OrderedDict | ||||
| import locale | ||||
| import os | ||||
| import re | ||||
| @@ -10,7 +11,6 @@ from importlib import import_module | ||||
| from threading import local | ||||
| import warnings | ||||
|  | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.encoding import force_str, force_text | ||||
| from django.utils.functional import memoize | ||||
| from django.utils._os import upath | ||||
| @@ -369,7 +369,7 @@ def get_supported_language_variant(lang_code, supported=None, strict=False): | ||||
|     """ | ||||
|     if supported is None: | ||||
|         from django.conf import settings | ||||
|         supported = SortedDict(settings.LANGUAGES) | ||||
|         supported = OrderedDict(settings.LANGUAGES) | ||||
|     if lang_code: | ||||
|         # if fr-CA is not supported, try fr-ca; if that fails, fallback to fr. | ||||
|         generic_lang_code = lang_code.split('-')[0] | ||||
| @@ -396,7 +396,7 @@ def get_language_from_path(path, supported=None, strict=False): | ||||
|     """ | ||||
|     if supported is None: | ||||
|         from django.conf import settings | ||||
|         supported = SortedDict(settings.LANGUAGES) | ||||
|         supported = OrderedDict(settings.LANGUAGES) | ||||
|     regex_match = language_code_prefix_re.match(path) | ||||
|     if not regex_match: | ||||
|         return None | ||||
| @@ -418,7 +418,7 @@ def get_language_from_request(request, check_path=False): | ||||
|     """ | ||||
|     global _accepted | ||||
|     from django.conf import settings | ||||
|     supported = SortedDict(settings.LANGUAGES) | ||||
|     supported = OrderedDict(settings.LANGUAGES) | ||||
|  | ||||
|     if check_path: | ||||
|         lang_code = get_language_from_path(request.path_info, supported) | ||||
|   | ||||
| @@ -423,6 +423,9 @@ these changes. | ||||
| * FastCGI support via the ``runfcgi`` management command will be | ||||
|   removed. Please deploy your project using WSGI. | ||||
|  | ||||
| * ``django.utils.datastructures.SortedDict`` will be removed. Use | ||||
|   :class:`collections.OrderedDict` from the Python standard library instead. | ||||
|  | ||||
| 2.0 | ||||
| --- | ||||
|  | ||||
|   | ||||
| @@ -977,14 +977,13 @@ of the arguments is required, but you should use at least one of them. | ||||
|   ``select_params`` parameter. Since ``select_params`` is a sequence and | ||||
|   the ``select`` attribute is a dictionary, some care is required so that | ||||
|   the parameters are matched up correctly with the extra select pieces. | ||||
|   In this situation, you should use a | ||||
|   :class:`django.utils.datastructures.SortedDict` for the ``select`` | ||||
|   value, not just a normal Python dictionary. | ||||
|   In this situation, you should use a :class:`collections.OrderedDict` for | ||||
|   the ``select`` value, not just a normal Python dictionary. | ||||
|  | ||||
|   This will work, for example:: | ||||
|  | ||||
|       Blog.objects.extra( | ||||
|           select=SortedDict([('a', '%s'), ('b', '%s')]), | ||||
|           select=OrderedDict([('a', '%s'), ('b', '%s')]), | ||||
|           select_params=('one', 'two')) | ||||
|  | ||||
|   The only thing to be careful about when using select parameters in | ||||
|   | ||||
| @@ -105,6 +105,10 @@ to distinguish caches by the ``Accept-language`` header. | ||||
|  | ||||
| .. class:: SortedDict | ||||
|  | ||||
| .. deprecated:: 1.7 | ||||
|     ``SortedDict`` is deprecated and will be removed in Django 1.9. Use | ||||
|     :class:`collections.OrderedDict` instead. | ||||
|  | ||||
|     The :class:`django.utils.datastructures.SortedDict` class is a dictionary | ||||
|     that keeps its keys in the order in which they're inserted. | ||||
|  | ||||
|   | ||||
| @@ -167,6 +167,13 @@ on all Python versions. Since ``unittest2`` became the standard library's | ||||
| Python versions, this module isn't useful anymore. It has been deprecated. Use | ||||
| :mod:`unittest` instead. | ||||
|  | ||||
| ``django.utils.datastructures.SortedDict`` | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| As :class:`~collections.OrderedDict` was added to the standard library in | ||||
| Python 2.7, :class:`~django.utils.datastructures.SortedDict` is no longer | ||||
| needed and has been deprecated. | ||||
|  | ||||
| Custom SQL location for models package | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from collections import OrderedDict | ||||
| import datetime | ||||
|  | ||||
| from django.contrib.auth.models import User | ||||
| from django.test import TestCase | ||||
| from django.utils.datastructures import SortedDict | ||||
|  | ||||
| from .models import TestObject, Order, RevisionableModel | ||||
|  | ||||
| @@ -74,7 +74,7 @@ class ExtraRegressTests(TestCase): | ||||
|         # select portions. Applies when portions are updated or otherwise | ||||
|         # moved around. | ||||
|         qs = User.objects.extra( | ||||
|                     select=SortedDict((("alpha", "%s"), ("beta", "2"),  ("gamma", "%s"))), | ||||
|                     select=OrderedDict((("alpha", "%s"), ("beta", "2"),  ("gamma", "%s"))), | ||||
|                     select_params=(1, 3) | ||||
|         ) | ||||
|         qs = qs.extra(select={"beta": 4}) | ||||
| @@ -180,100 +180,100 @@ class ExtraRegressTests(TestCase): | ||||
|         obj.save() | ||||
|  | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values()), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values()), | ||||
|             [{'bar': 'second', 'third': 'third', 'second': 'second', 'whiz': 'third', 'foo': 'first', 'id': obj.pk, 'first': 'first'}] | ||||
|         ) | ||||
|  | ||||
|         # Extra clauses after an empty values clause are still included | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.values().extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), | ||||
|             list(TestObject.objects.values().extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), | ||||
|             [{'bar': 'second', 'third': 'third', 'second': 'second', 'whiz': 'third', 'foo': 'first', 'id': obj.pk, 'first': 'first'}] | ||||
|         ) | ||||
|  | ||||
|         # Extra columns are ignored if not mentioned in the values() clause | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second')), | ||||
|             [{'second': 'second', 'first': 'first'}] | ||||
|         ) | ||||
|  | ||||
|         # Extra columns after a non-empty values() clause are ignored | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.values('first', 'second').extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), | ||||
|             list(TestObject.objects.values('first', 'second').extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), | ||||
|             [{'second': 'second', 'first': 'first'}] | ||||
|         ) | ||||
|  | ||||
|         # Extra columns can be partially returned | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second', 'foo')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second', 'foo')), | ||||
|             [{'second': 'second', 'foo': 'first', 'first': 'first'}] | ||||
|         ) | ||||
|  | ||||
|         # Also works if only extra columns are included | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('foo', 'whiz')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('foo', 'whiz')), | ||||
|             [{'foo': 'first', 'whiz': 'third'}] | ||||
|         ) | ||||
|  | ||||
|         # Values list works the same way | ||||
|         # All columns are returned for an empty values_list() | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list()), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list()), | ||||
|             [('first', 'second', 'third', obj.pk, 'first', 'second', 'third')] | ||||
|         ) | ||||
|  | ||||
|         # Extra columns after an empty values_list() are still included | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.values_list().extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), | ||||
|             list(TestObject.objects.values_list().extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), | ||||
|             [('first', 'second', 'third', obj.pk, 'first', 'second', 'third')] | ||||
|         ) | ||||
|  | ||||
|         # Extra columns ignored completely if not mentioned in values_list() | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second')), | ||||
|             [('first', 'second')] | ||||
|         ) | ||||
|  | ||||
|         # Extra columns after a non-empty values_list() clause are ignored completely | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.values_list('first', 'second').extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), | ||||
|             list(TestObject.objects.values_list('first', 'second').extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), | ||||
|             [('first', 'second')] | ||||
|         ) | ||||
|  | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('second', flat=True)), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('second', flat=True)), | ||||
|             ['second'] | ||||
|         ) | ||||
|  | ||||
|         # Only the extra columns specified in the values_list() are returned | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second', 'whiz')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second', 'whiz')), | ||||
|             [('first', 'second', 'third')] | ||||
|         ) | ||||
|  | ||||
|         # ...also works if only extra columns are included | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('foo','whiz')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('foo','whiz')), | ||||
|             [('first', 'third')] | ||||
|         ) | ||||
|  | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', flat=True)), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', flat=True)), | ||||
|             ['third'] | ||||
|         ) | ||||
|  | ||||
|         # ... and values are returned in the order they are specified | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz','foo')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz','foo')), | ||||
|             [('third', 'first')] | ||||
|         ) | ||||
|  | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first','id')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first','id')), | ||||
|             [('first', obj.pk)] | ||||
|         ) | ||||
|  | ||||
|         self.assertEqual( | ||||
|             list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', 'first', 'bar', 'id')), | ||||
|             list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', 'first', 'bar', 'id')), | ||||
|             [('third', 'first', 'second', obj.pk)] | ||||
|         ) | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from collections import OrderedDict | ||||
| import datetime | ||||
| from operator import attrgetter | ||||
| import pickle | ||||
| @@ -14,7 +15,6 @@ from django.db.models.sql.where import WhereNode, EverythingNode, NothingNode | ||||
| from django.db.models.sql.datastructures import EmptyResultSet | ||||
| from django.test import TestCase, skipUnlessDBFeature | ||||
| from django.test.utils import str_prefix | ||||
| from django.utils.datastructures import SortedDict | ||||
|  | ||||
| from .models import ( | ||||
|     Annotation, Article, Author, Celebrity, Child, Cover, Detail, DumbCategory, | ||||
| @@ -499,7 +499,7 @@ class Queries1Tests(BaseQuerysetTest): | ||||
|         ) | ||||
|  | ||||
|     def test_ticket2902(self): | ||||
|         # Parameters can be given to extra_select, *if* you use a SortedDict. | ||||
|         # Parameters can be given to extra_select, *if* you use an OrderedDict. | ||||
|  | ||||
|         # (First we need to know which order the keys fall in "naturally" on | ||||
|         # your system, so we can put things in the wrong way around from | ||||
| @@ -513,7 +513,7 @@ class Queries1Tests(BaseQuerysetTest): | ||||
|         # This slightly odd comparison works around the fact that PostgreSQL will | ||||
|         # return 'one' and 'two' as strings, not Unicode objects. It's a side-effect of | ||||
|         # using constants here and not a real concern. | ||||
|         d = Item.objects.extra(select=SortedDict(s), select_params=params).values('a', 'b')[0] | ||||
|         d = Item.objects.extra(select=OrderedDict(s), select_params=params).values('a', 'b')[0] | ||||
|         self.assertEqual(d, {'a': 'one', 'b': 'two'}) | ||||
|  | ||||
|         # Order by the number of tags attached to an item. | ||||
| @@ -1987,7 +1987,7 @@ class ValuesQuerysetTests(BaseQuerysetTest): | ||||
|  | ||||
|     def test_extra_values(self): | ||||
|         # testing for ticket 14930 issues | ||||
|         qs = Number.objects.extra(select=SortedDict([('value_plus_x', 'num+%s'), | ||||
|         qs = Number.objects.extra(select=OrderedDict([('value_plus_x', 'num+%s'), | ||||
|                                                      ('value_minus_x', 'num-%s')]), | ||||
|                                   select_params=(1, 2)) | ||||
|         qs = qs.order_by('value_minus_x') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user