mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Merge branch 'master' into schema-alteration
This commit is contained in:
		| @@ -158,7 +158,7 @@ class UserSettingsHolder(BaseSettings): | ||||
|         return getattr(self.default_settings, name) | ||||
|  | ||||
|     def __dir__(self): | ||||
|         return self.__dict__.keys() + dir(self.default_settings) | ||||
|         return list(self.__dict__) + dir(self.default_settings) | ||||
|  | ||||
|     # For Python < 2.6: | ||||
|     __members__ = property(lambda self: self.__dir__()) | ||||
|   | ||||
| @@ -7,7 +7,7 @@ from __future__ import unicode_literals | ||||
| # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date | ||||
| DATE_FORMAT = 'j. E Y' | ||||
| TIME_FORMAT = 'G.i.s' | ||||
| # DATETIME_FORMAT =  | ||||
| DATETIME_FORMAT = r'j. E Y \k\e\l\l\o G.i.s' | ||||
| YEAR_MONTH_FORMAT = 'F Y' | ||||
| MONTH_DAY_FORMAT = 'j. F' | ||||
| SHORT_DATE_FORMAT = 'j.n.Y' | ||||
|   | ||||
| @@ -1,17 +1,18 @@ | ||||
| # -*- encoding: utf-8 -*- | ||||
| # This file is distributed under the same license as the Django package. | ||||
| # | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| # The *_FORMAT strings use the Django date format syntax, | ||||
| # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date | ||||
| DATE_FORMAT = 'd F Y' | ||||
| DATE_FORMAT = r'j \d\e F \d\e Y' | ||||
| TIME_FORMAT = 'H:i:s' | ||||
| # DATETIME_FORMAT =  | ||||
| YEAR_MONTH_FORMAT = 'F Y' | ||||
| MONTH_DAY_FORMAT = 'j F' | ||||
| SHORT_DATE_FORMAT = 'j M, Y' | ||||
| # SHORT_DATETIME_FORMAT =  | ||||
| # FIRST_DAY_OF_WEEK =  | ||||
| DATETIME_FORMAT = r'j \d\e F \d\e Y \á\s H:i' | ||||
| YEAR_MONTH_FORMAT = r'F \d\e Y' | ||||
| MONTH_DAY_FORMAT = r'j \d\e F' | ||||
| SHORT_DATE_FORMAT = 'd-m-Y' | ||||
| SHORT_DATETIME_FORMAT = 'd-m-Y, H:i' | ||||
| FIRST_DAY_OF_WEEK = 1 # Monday | ||||
|  | ||||
| # The *_INPUT_FORMATS strings use the Python strftime format syntax, | ||||
| # see http://docs.python.org/library/datetime.html#strftime-strptime-behavior | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| from django.conf import settings | ||||
| from django.conf.urls import patterns | ||||
| from django.conf.urls import patterns, url | ||||
| from django.core.urlresolvers import LocaleRegexURLResolver | ||||
|  | ||||
| def i18n_patterns(prefix, *args): | ||||
| @@ -16,5 +16,5 @@ def i18n_patterns(prefix, *args): | ||||
|  | ||||
|  | ||||
| urlpatterns = patterns('', | ||||
|     (r'^setlang/$', 'django.views.i18n.set_language'), | ||||
|     url(r'^setlang/$', 'django.views.i18n.set_language', name='set_language'), | ||||
| ) | ||||
|   | ||||
| @@ -7,7 +7,7 @@ from django.contrib.admin import helpers | ||||
| from django.contrib.admin.util import get_deleted_objects, model_ngettext | ||||
| from django.db import router | ||||
| from django.template.response import TemplateResponse | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils.translation import ugettext_lazy, ugettext as _ | ||||
|  | ||||
| def delete_selected(modeladmin, request, queryset): | ||||
| @@ -42,7 +42,7 @@ def delete_selected(modeladmin, request, queryset): | ||||
|         n = queryset.count() | ||||
|         if n: | ||||
|             for obj in queryset: | ||||
|                 obj_display = force_unicode(obj) | ||||
|                 obj_display = force_text(obj) | ||||
|                 modeladmin.log_deletion(request, obj, obj_display) | ||||
|             queryset.delete() | ||||
|             modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % { | ||||
| @@ -52,9 +52,9 @@ def delete_selected(modeladmin, request, queryset): | ||||
|         return None | ||||
|  | ||||
|     if len(queryset) == 1: | ||||
|         objects_name = force_unicode(opts.verbose_name) | ||||
|         objects_name = force_text(opts.verbose_name) | ||||
|     else: | ||||
|         objects_name = force_unicode(opts.verbose_name_plural) | ||||
|         objects_name = force_text(opts.verbose_name_plural) | ||||
|  | ||||
|     if perms_needed or protected: | ||||
|         title = _("Cannot delete %(name)s") % {"name": objects_name} | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import datetime | ||||
|  | ||||
| from django.db import models | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from django.utils import timezone | ||||
|  | ||||
| @@ -195,7 +195,7 @@ class RelatedFieldListFilter(FieldListFilter): | ||||
|         } | ||||
|         for pk_val, val in self.lookup_choices: | ||||
|             yield { | ||||
|                 'selected': self.lookup_val == smart_unicode(pk_val), | ||||
|                 'selected': self.lookup_val == smart_text(pk_val), | ||||
|                 'query_string': cl.get_query_string({ | ||||
|                     self.lookup_kwarg: pk_val, | ||||
|                 }, [self.lookup_kwarg_isnull]), | ||||
| @@ -272,7 +272,7 @@ class ChoicesFieldListFilter(FieldListFilter): | ||||
|         } | ||||
|         for lookup, title in self.field.flatchoices: | ||||
|             yield { | ||||
|                 'selected': smart_unicode(lookup) == self.lookup_val, | ||||
|                 'selected': smart_text(lookup) == self.lookup_val, | ||||
|                 'query_string': cl.get_query_string({ | ||||
|                                     self.lookup_kwarg: lookup}), | ||||
|                 'display': title, | ||||
| @@ -381,7 +381,7 @@ class AllValuesFieldListFilter(FieldListFilter): | ||||
|             if val is None: | ||||
|                 include_none = True | ||||
|                 continue | ||||
|             val = smart_unicode(val) | ||||
|             val = smart_text(val) | ||||
|             yield { | ||||
|                 'selected': self.lookup_val == val, | ||||
|                 'query_string': cl.get_query_string({ | ||||
|   | ||||
| @@ -9,7 +9,7 @@ from django.core.exceptions import ObjectDoesNotExist | ||||
| from django.db.models.fields.related import ManyToManyRel | ||||
| from django.forms.util import flatatt | ||||
| from django.template.defaultfilters import capfirst | ||||
| from django.utils.encoding import force_unicode, smart_unicode | ||||
| from django.utils.encoding import force_text, smart_text | ||||
| from django.utils.html import conditional_escape, format_html | ||||
| from django.utils.safestring import mark_safe | ||||
| from django.utils import six | ||||
| @@ -94,7 +94,7 @@ class Fieldset(object): | ||||
| class Fieldline(object): | ||||
|     def __init__(self, form, field, readonly_fields=None, model_admin=None): | ||||
|         self.form = form # A django.forms.Form instance | ||||
|         if not hasattr(field, "__iter__"): | ||||
|         if not hasattr(field, "__iter__") or isinstance(field, six.text_type): | ||||
|             self.fields = [field] | ||||
|         else: | ||||
|             self.fields = field | ||||
| @@ -122,7 +122,7 @@ class AdminField(object): | ||||
|  | ||||
|     def label_tag(self): | ||||
|         classes = [] | ||||
|         contents = conditional_escape(force_unicode(self.field.label)) | ||||
|         contents = conditional_escape(force_text(self.field.label)) | ||||
|         if self.is_checkbox: | ||||
|             classes.append('vCheckboxLabel') | ||||
|         else: | ||||
| @@ -166,7 +166,7 @@ class AdminReadonlyField(object): | ||||
|         label = self.field['label'] | ||||
|         return format_html('<label{0}>{1}:</label>', | ||||
|                            flatatt(attrs), | ||||
|                            capfirst(force_unicode(label))) | ||||
|                            capfirst(force_text(label))) | ||||
|  | ||||
|     def contents(self): | ||||
|         from django.contrib.admin.templatetags.admin_list import _boolean_icon | ||||
| @@ -182,7 +182,7 @@ class AdminReadonlyField(object): | ||||
|                 if boolean: | ||||
|                     result_repr = _boolean_icon(value) | ||||
|                 else: | ||||
|                     result_repr = smart_unicode(value) | ||||
|                     result_repr = smart_text(value) | ||||
|                     if getattr(attr, "allow_tags", False): | ||||
|                         result_repr = mark_safe(result_repr) | ||||
|             else: | ||||
| @@ -325,11 +325,11 @@ class AdminErrorList(forms.util.ErrorList): | ||||
|     """ | ||||
|     def __init__(self, form, inline_formsets): | ||||
|         if form.is_bound: | ||||
|             self.extend(form.errors.values()) | ||||
|             self.extend(list(six.itervalues(form.errors))) | ||||
|             for inline_formset in inline_formsets: | ||||
|                 self.extend(inline_formset.non_form_errors()) | ||||
|                 for errors_in_inline_form in inline_formset.errors: | ||||
|                     self.extend(errors_in_inline_form.values()) | ||||
|                     self.extend(list(six.itervalues(errors_in_inline_form))) | ||||
|  | ||||
| def normalize_fieldsets(fieldsets): | ||||
|     """ | ||||
|   | ||||
| @@ -5,7 +5,7 @@ from django.contrib.contenttypes.models import ContentType | ||||
| from django.contrib.auth.models import User | ||||
| from django.contrib.admin.util import quote | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
|  | ||||
| ADDITION = 1 | ||||
| CHANGE = 2 | ||||
| @@ -13,7 +13,7 @@ DELETION = 3 | ||||
|  | ||||
| class LogEntryManager(models.Manager): | ||||
|     def log_action(self, user_id, content_type_id, object_id, object_repr, action_flag, change_message=''): | ||||
|         e = self.model(None, None, user_id, content_type_id, smart_unicode(object_id), object_repr[:200], action_flag, change_message) | ||||
|         e = self.model(None, None, user_id, content_type_id, smart_text(object_id), object_repr[:200], action_flag, change_message) | ||||
|         e.save() | ||||
|  | ||||
| class LogEntry(models.Model): | ||||
| @@ -34,7 +34,7 @@ class LogEntry(models.Model): | ||||
|         ordering = ('-action_time',) | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return smart_unicode(self.action_time) | ||||
|         return smart_text(self.action_time) | ||||
|  | ||||
|     def __unicode__(self): | ||||
|         if self.action_flag == ADDITION: | ||||
|   | ||||
| @@ -28,7 +28,7 @@ from django.utils import six | ||||
| from django.utils.text import capfirst, get_text_list | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.utils.translation import ungettext | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
|  | ||||
| HORIZONTAL, VERTICAL = 1, 2 | ||||
| # returns the <ul> class for a given radio_admin field | ||||
| @@ -425,7 +425,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         if self.declared_fieldsets: | ||||
|             return self.declared_fieldsets | ||||
|         form = self.get_form(request, obj) | ||||
|         fields = form.base_fields.keys() + list(self.get_readonly_fields(request, obj)) | ||||
|         fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj)) | ||||
|         return [(None, {'fields': fields})] | ||||
|  | ||||
|     def get_form(self, request, obj=None, **kwargs): | ||||
| @@ -520,7 +520,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             user_id         = request.user.pk, | ||||
|             content_type_id = ContentType.objects.get_for_model(object).pk, | ||||
|             object_id       = object.pk, | ||||
|             object_repr     = force_unicode(object), | ||||
|             object_repr     = force_text(object), | ||||
|             action_flag     = ADDITION | ||||
|         ) | ||||
|  | ||||
| @@ -535,7 +535,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             user_id         = request.user.pk, | ||||
|             content_type_id = ContentType.objects.get_for_model(object).pk, | ||||
|             object_id       = object.pk, | ||||
|             object_repr     = force_unicode(object), | ||||
|             object_repr     = force_text(object), | ||||
|             action_flag     = CHANGE, | ||||
|             change_message  = message | ||||
|         ) | ||||
| @@ -560,7 +560,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         """ | ||||
|         A list_display column containing a checkbox widget. | ||||
|         """ | ||||
|         return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_unicode(obj.pk)) | ||||
|         return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk)) | ||||
|     action_checkbox.short_description = mark_safe('<input type="checkbox" id="action-toggle" />') | ||||
|     action_checkbox.allow_tags = True | ||||
|  | ||||
| @@ -608,7 +608,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         tuple (name, description). | ||||
|         """ | ||||
|         choices = [] + default_choices | ||||
|         for func, name, description in self.get_actions(request).itervalues(): | ||||
|         for func, name, description in six.itervalues(self.get_actions(request)): | ||||
|             choice = (name, description % model_format_dict(self.opts)) | ||||
|             choices.append(choice) | ||||
|         return choices | ||||
| @@ -674,17 +674,17 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             for formset in formsets: | ||||
|                 for added_object in formset.new_objects: | ||||
|                     change_message.append(_('Added %(name)s "%(object)s".') | ||||
|                                           % {'name': force_unicode(added_object._meta.verbose_name), | ||||
|                                              'object': force_unicode(added_object)}) | ||||
|                                           % {'name': force_text(added_object._meta.verbose_name), | ||||
|                                              'object': force_text(added_object)}) | ||||
|                 for changed_object, changed_fields in formset.changed_objects: | ||||
|                     change_message.append(_('Changed %(list)s for %(name)s "%(object)s".') | ||||
|                                           % {'list': get_text_list(changed_fields, _('and')), | ||||
|                                              'name': force_unicode(changed_object._meta.verbose_name), | ||||
|                                              'object': force_unicode(changed_object)}) | ||||
|                                              'name': force_text(changed_object._meta.verbose_name), | ||||
|                                              'object': force_text(changed_object)}) | ||||
|                 for deleted_object in formset.deleted_objects: | ||||
|                     change_message.append(_('Deleted %(name)s "%(object)s".') | ||||
|                                           % {'name': force_unicode(deleted_object._meta.verbose_name), | ||||
|                                              'object': force_unicode(deleted_object)}) | ||||
|                                           % {'name': force_text(deleted_object._meta.verbose_name), | ||||
|                                              'object': force_text(deleted_object)}) | ||||
|         change_message = ' '.join(change_message) | ||||
|         return change_message or _('No fields changed.') | ||||
|  | ||||
| @@ -769,7 +769,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         opts = obj._meta | ||||
|         pk_value = obj._get_pk_val() | ||||
|  | ||||
|         msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)} | ||||
|         msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_text(opts.verbose_name), 'obj': force_text(obj)} | ||||
|         # Here, we distinguish between different save types by checking for | ||||
|         # the presence of keys in request.POST. | ||||
|         if "_continue" in request.POST: | ||||
| @@ -782,10 +782,10 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             return HttpResponse( | ||||
|                 '<!DOCTYPE html><html><head><title></title></head><body>' | ||||
|                 '<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script></body></html>' % \ | ||||
|                 # escape() calls force_unicode. | ||||
|                 # escape() calls force_text. | ||||
|                 (escape(pk_value), escapejs(obj))) | ||||
|         elif "_addanother" in request.POST: | ||||
|             self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) | ||||
|             self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_text(opts.verbose_name))) | ||||
|             return HttpResponseRedirect(request.path) | ||||
|         else: | ||||
|             self.message_user(request, msg) | ||||
| @@ -819,7 +819,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|  | ||||
|         pk_value = obj._get_pk_val() | ||||
|  | ||||
|         msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(verbose_name), 'obj': force_unicode(obj)} | ||||
|         msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_text(verbose_name), 'obj': force_text(obj)} | ||||
|         if "_continue" in request.POST: | ||||
|             self.message_user(request, msg + ' ' + _("You may edit it again below.")) | ||||
|             if "_popup" in request.REQUEST: | ||||
| @@ -827,14 +827,14 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             else: | ||||
|                 return HttpResponseRedirect(request.path) | ||||
|         elif "_saveasnew" in request.POST: | ||||
|             msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(verbose_name), 'obj': obj} | ||||
|             msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_text(verbose_name), 'obj': obj} | ||||
|             self.message_user(request, msg) | ||||
|             return HttpResponseRedirect(reverse('admin:%s_%s_change' % | ||||
|                                         (opts.app_label, module_name), | ||||
|                                         args=(pk_value,), | ||||
|                                         current_app=self.admin_site.name)) | ||||
|         elif "_addanother" in request.POST: | ||||
|             self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(verbose_name))) | ||||
|             self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_text(verbose_name))) | ||||
|             return HttpResponseRedirect(reverse('admin:%s_%s_add' % | ||||
|                                         (opts.app_label, module_name), | ||||
|                                         current_app=self.admin_site.name)) | ||||
| @@ -995,7 +995,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             media = media + inline_admin_formset.media | ||||
|  | ||||
|         context = { | ||||
|             'title': _('Add %s') % force_unicode(opts.verbose_name), | ||||
|             'title': _('Add %s') % force_text(opts.verbose_name), | ||||
|             'adminform': adminForm, | ||||
|             'is_popup': "_popup" in request.REQUEST, | ||||
|             'media': media, | ||||
| @@ -1019,7 +1019,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             raise PermissionDenied | ||||
|  | ||||
|         if obj is None: | ||||
|             raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)}) | ||||
|             raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)}) | ||||
|  | ||||
|         if request.method == 'POST' and "_saveasnew" in request.POST: | ||||
|             return self.add_view(request, form_url=reverse('admin:%s_%s_add' % | ||||
| @@ -1085,7 +1085,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             media = media + inline_admin_formset.media | ||||
|  | ||||
|         context = { | ||||
|             'title': _('Change %s') % force_unicode(opts.verbose_name), | ||||
|             'title': _('Change %s') % force_text(opts.verbose_name), | ||||
|             'adminform': adminForm, | ||||
|             'object_id': object_id, | ||||
|             'original': obj, | ||||
| @@ -1194,14 +1194,14 @@ class ModelAdmin(BaseModelAdmin): | ||||
|  | ||||
|                 if changecount: | ||||
|                     if changecount == 1: | ||||
|                         name = force_unicode(opts.verbose_name) | ||||
|                         name = force_text(opts.verbose_name) | ||||
|                     else: | ||||
|                         name = force_unicode(opts.verbose_name_plural) | ||||
|                         name = force_text(opts.verbose_name_plural) | ||||
|                     msg = ungettext("%(count)s %(name)s was changed successfully.", | ||||
|                                     "%(count)s %(name)s were changed successfully.", | ||||
|                                     changecount) % {'count': changecount, | ||||
|                                                     'name': name, | ||||
|                                                     'obj': force_unicode(obj)} | ||||
|                                                     'obj': force_text(obj)} | ||||
|                     self.message_user(request, msg) | ||||
|  | ||||
|                 return HttpResponseRedirect(request.get_full_path()) | ||||
| @@ -1228,7 +1228,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             'All %(total_count)s selected', cl.result_count) | ||||
|  | ||||
|         context = { | ||||
|             'module_name': force_unicode(opts.verbose_name_plural), | ||||
|             'module_name': force_text(opts.verbose_name_plural), | ||||
|             'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)}, | ||||
|             'selection_note_all': selection_note_all % {'total_count': cl.result_count}, | ||||
|             'title': cl.title, | ||||
| @@ -1263,7 +1263,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             raise PermissionDenied | ||||
|  | ||||
|         if obj is None: | ||||
|             raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)}) | ||||
|             raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)}) | ||||
|  | ||||
|         using = router.db_for_write(self.model) | ||||
|  | ||||
| @@ -1275,11 +1275,11 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         if request.POST: # The user has already confirmed the deletion. | ||||
|             if perms_needed: | ||||
|                 raise PermissionDenied | ||||
|             obj_display = force_unicode(obj) | ||||
|             obj_display = force_text(obj) | ||||
|             self.log_deletion(request, obj, obj_display) | ||||
|             self.delete_model(request, obj) | ||||
|  | ||||
|             self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)}) | ||||
|             self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_text(opts.verbose_name), 'obj': force_text(obj_display)}) | ||||
|  | ||||
|             if not self.has_change_permission(request, None): | ||||
|                 return HttpResponseRedirect(reverse('admin:index', | ||||
| @@ -1288,7 +1288,7 @@ class ModelAdmin(BaseModelAdmin): | ||||
|                                         (opts.app_label, opts.module_name), | ||||
|                                         current_app=self.admin_site.name)) | ||||
|  | ||||
|         object_name = force_unicode(opts.verbose_name) | ||||
|         object_name = force_text(opts.verbose_name) | ||||
|  | ||||
|         if perms_needed or protected: | ||||
|             title = _("Cannot delete %(name)s") % {"name": object_name} | ||||
| @@ -1326,9 +1326,9 @@ class ModelAdmin(BaseModelAdmin): | ||||
|         # If no history was found, see whether this object even exists. | ||||
|         obj = get_object_or_404(model, pk=unquote(object_id)) | ||||
|         context = { | ||||
|             'title': _('Change history: %s') % force_unicode(obj), | ||||
|             'title': _('Change history: %s') % force_text(obj), | ||||
|             'action_list': action_list, | ||||
|             'module_name': capfirst(force_unicode(opts.verbose_name_plural)), | ||||
|             'module_name': capfirst(force_text(opts.verbose_name_plural)), | ||||
|             'object': obj, | ||||
|             'app_label': app_label, | ||||
|             'opts': opts, | ||||
| @@ -1415,7 +1415,7 @@ class InlineModelAdmin(BaseModelAdmin): | ||||
|         if self.declared_fieldsets: | ||||
|             return self.declared_fieldsets | ||||
|         form = self.get_formset(request, obj).form | ||||
|         fields = form.base_fields.keys() + list(self.get_readonly_fields(request, obj)) | ||||
|         fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj)) | ||||
|         return [(None, {'fields': fields})] | ||||
|  | ||||
|     def queryset(self, request): | ||||
|   | ||||
| @@ -10,6 +10,7 @@ from django.core.exceptions import ImproperlyConfigured | ||||
| from django.core.urlresolvers import reverse, NoReverseMatch | ||||
| from django.template.response import TemplateResponse | ||||
| from django.utils.safestring import mark_safe | ||||
| from django.utils import six | ||||
| from django.utils.text import capfirst | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.views.decorators.cache import never_cache | ||||
| @@ -133,7 +134,7 @@ class AdminSite(object): | ||||
|         """ | ||||
|         Get all the enabled actions as an iterable of (name, func). | ||||
|         """ | ||||
|         return self._actions.iteritems() | ||||
|         return six.iteritems(self._actions) | ||||
|  | ||||
|     def has_permission(self, request): | ||||
|         """ | ||||
| @@ -239,7 +240,7 @@ class AdminSite(object): | ||||
|         ) | ||||
|  | ||||
|         # Add in each model's views. | ||||
|         for model, model_admin in self._registry.iteritems(): | ||||
|         for model, model_admin in six.iteritems(self._registry): | ||||
|             urlpatterns += patterns('', | ||||
|                 url(r'^%s/%s/' % (model._meta.app_label, model._meta.module_name), | ||||
|                     include(model_admin.urls)) | ||||
| @@ -370,7 +371,7 @@ class AdminSite(object): | ||||
|                         } | ||||
|  | ||||
|         # Sort the apps alphabetically. | ||||
|         app_list = app_dict.values() | ||||
|         app_list = list(six.itervalues(app_dict)) | ||||
|         app_list.sort(key=lambda x: x['name']) | ||||
|  | ||||
|         # Sort the models alphabetically within each app. | ||||
|   | ||||
| @@ -12,9 +12,10 @@ from django.db import models | ||||
| from django.utils import formats | ||||
| from django.utils.html import format_html | ||||
| from django.utils.safestring import mark_safe | ||||
| from django.utils import six | ||||
| from django.utils.text import capfirst | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.utils.encoding import smart_unicode, force_unicode | ||||
| from django.utils.encoding import smart_text, force_text | ||||
| from django.template import Library | ||||
| from django.template.loader import get_template | ||||
| from django.template.context import Context | ||||
| @@ -125,7 +126,7 @@ def result_headers(cl): | ||||
|         if i in ordering_field_columns: | ||||
|             sorted = True | ||||
|             order_type = ordering_field_columns.get(i).lower() | ||||
|             sort_priority = ordering_field_columns.keys().index(i) + 1 | ||||
|             sort_priority = list(ordering_field_columns).index(i) + 1 | ||||
|             th_classes.append('sorted %sending' % order_type) | ||||
|             new_order_type = {'asc': 'desc', 'desc': 'asc'}[order_type] | ||||
|  | ||||
| @@ -209,7 +210,7 @@ def items_for_result(cl, result, form): | ||||
|                     result_repr = display_for_field(value, f) | ||||
|                 if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)): | ||||
|                     row_class = mark_safe(' class="nowrap"') | ||||
|         if force_unicode(result_repr) == '': | ||||
|         if force_text(result_repr) == '': | ||||
|             result_repr = mark_safe(' ') | ||||
|         # If list_display_links not defined, add the link tag to the first field | ||||
|         if (first and not cl.list_display_links) or field_name in cl.list_display_links: | ||||
| @@ -223,7 +224,7 @@ def items_for_result(cl, result, form): | ||||
|             else: | ||||
|                 attr = pk | ||||
|             value = result.serializable_value(attr) | ||||
|             result_id = repr(force_unicode(value))[1:] | ||||
|             result_id = repr(force_text(value))[1:] | ||||
|             yield format_html('<{0}{1}><a href="{2}"{3}>{4}</a></{5}>', | ||||
|                               table_tag, | ||||
|                               row_class, | ||||
| @@ -240,10 +241,10 @@ def items_for_result(cl, result, form): | ||||
|                     field_name == cl.model._meta.pk.name and | ||||
|                         form[cl.model._meta.pk.name].is_hidden)): | ||||
|                 bf = form[field_name] | ||||
|                 result_repr = mark_safe(force_unicode(bf.errors) + force_unicode(bf)) | ||||
|                 result_repr = mark_safe(force_text(bf.errors) + force_text(bf)) | ||||
|             yield format_html('<td{0}>{1}</td>', row_class, result_repr) | ||||
|     if form and not form[cl.model._meta.pk.name].is_hidden: | ||||
|         yield format_html('<td>{0}</td>', force_unicode(form[cl.model._meta.pk.name])) | ||||
|         yield format_html('<td>{0}</td>', force_text(form[cl.model._meta.pk.name])) | ||||
|  | ||||
| class ResultList(list): | ||||
|     # Wrapper class used to return items in a list_editable | ||||
| @@ -266,7 +267,7 @@ def result_hidden_fields(cl): | ||||
|     if cl.formset: | ||||
|         for res, form in zip(cl.result_list, cl.formset.forms): | ||||
|             if form[cl.model._meta.pk.name].is_hidden: | ||||
|                 yield mark_safe(force_unicode(form[cl.model._meta.pk.name])) | ||||
|                 yield mark_safe(force_text(form[cl.model._meta.pk.name])) | ||||
|  | ||||
| @register.inclusion_tag("admin/change_list_results.html") | ||||
| def result_list(cl): | ||||
|   | ||||
| @@ -12,7 +12,7 @@ from django.utils import formats | ||||
| from django.utils.html import format_html | ||||
| from django.utils.text import capfirst | ||||
| from django.utils import timezone | ||||
| from django.utils.encoding import force_unicode, smart_unicode, smart_str | ||||
| from django.utils.encoding import force_text, smart_text, smart_bytes | ||||
| from django.utils import six | ||||
| from django.utils.translation import ungettext | ||||
| from django.core.urlresolvers import reverse | ||||
| @@ -132,7 +132,7 @@ def get_deleted_objects(objs, opts, user, admin_site, using): | ||||
|             # Don't display link to edit, because it either has no | ||||
|             # admin or is edited inline. | ||||
|             return '%s: %s' % (capfirst(opts.verbose_name), | ||||
|                                 force_unicode(obj)) | ||||
|                                 force_text(obj)) | ||||
|  | ||||
|     to_delete = collector.nested(format_callback) | ||||
|  | ||||
| @@ -207,8 +207,8 @@ def model_format_dict(obj): | ||||
|     else: | ||||
|         opts = obj | ||||
|     return { | ||||
|         'verbose_name': force_unicode(opts.verbose_name), | ||||
|         'verbose_name_plural': force_unicode(opts.verbose_name_plural) | ||||
|         'verbose_name': force_text(opts.verbose_name), | ||||
|         'verbose_name_plural': force_text(opts.verbose_name_plural) | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -274,10 +274,10 @@ def label_for_field(name, model, model_admin=None, return_attr=False): | ||||
|             label = field.verbose_name | ||||
|     except models.FieldDoesNotExist: | ||||
|         if name == "__unicode__": | ||||
|             label = force_unicode(model._meta.verbose_name) | ||||
|             label = force_text(model._meta.verbose_name) | ||||
|             attr = six.text_type | ||||
|         elif name == "__str__": | ||||
|             label = smart_str(model._meta.verbose_name) | ||||
|             label = smart_bytes(model._meta.verbose_name) | ||||
|             attr = bytes | ||||
|         else: | ||||
|             if callable(name): | ||||
| @@ -311,7 +311,7 @@ def help_text_for_field(name, model): | ||||
|         help_text = model._meta.get_field_by_name(name)[0].help_text | ||||
|     except models.FieldDoesNotExist: | ||||
|         help_text = "" | ||||
|     return smart_unicode(help_text) | ||||
|     return smart_text(help_text) | ||||
|  | ||||
|  | ||||
| def display_for_field(value, field): | ||||
| @@ -335,7 +335,7 @@ def display_for_field(value, field): | ||||
|     elif isinstance(field, models.FloatField): | ||||
|         return formats.number_format(value) | ||||
|     else: | ||||
|         return smart_unicode(value) | ||||
|         return smart_text(value) | ||||
|  | ||||
|  | ||||
| def display_for_value(value, boolean=False): | ||||
| @@ -353,7 +353,7 @@ def display_for_value(value, boolean=False): | ||||
|     elif isinstance(value, six.integer_types + (decimal.Decimal, float)): | ||||
|         return formats.number_format(value) | ||||
|     else: | ||||
|         return smart_unicode(value) | ||||
|         return smart_text(value) | ||||
|  | ||||
|  | ||||
| class NotRelationField(Exception): | ||||
|   | ||||
| @@ -6,7 +6,7 @@ from django.core.paginator import InvalidPage | ||||
| from django.db import models | ||||
| from django.db.models.fields import FieldDoesNotExist | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.encoding import force_unicode, smart_str | ||||
| from django.utils.encoding import force_text, smart_bytes | ||||
| from django.utils.translation import ugettext, ugettext_lazy | ||||
| from django.utils.http import urlencode | ||||
|  | ||||
| @@ -75,7 +75,7 @@ class ChangeList(object): | ||||
|             title = ugettext('Select %s') | ||||
|         else: | ||||
|             title = ugettext('Select %s to change') | ||||
|         self.title = title % force_unicode(self.opts.verbose_name) | ||||
|         self.title = title % force_text(self.opts.verbose_name) | ||||
|         self.pk_attname = self.lookup_opts.pk.attname | ||||
|  | ||||
|     def get_filters(self, request): | ||||
| @@ -94,7 +94,7 @@ class ChangeList(object): | ||||
|                 # 'key' will be used as a keyword argument later, so Python | ||||
|                 # requires it to be a string. | ||||
|                 del lookup_params[key] | ||||
|                 lookup_params[smart_str(key)] = value | ||||
|                 lookup_params[smart_bytes(key)] = value | ||||
|  | ||||
|             if not self.model_admin.lookup_allowed(key, value): | ||||
|                 raise SuspiciousOperation("Filtering by %s not allowed" % key) | ||||
|   | ||||
| @@ -14,7 +14,7 @@ from django.utils.html import escape, format_html, format_html_join | ||||
| from django.utils.text import Truncator | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.utils.safestring import mark_safe | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils import six | ||||
|  | ||||
|  | ||||
| @@ -96,7 +96,7 @@ class AdminRadioFieldRenderer(RadioFieldRenderer): | ||||
|         return format_html('<ul{0}>\n{1}\n</ul>', | ||||
|                            flatatt(self.attrs), | ||||
|                            format_html_join('\n', '<li>{0}</li>', | ||||
|                                             ((force_unicode(w),) for w in self))) | ||||
|                                             ((force_text(w),) for w in self))) | ||||
|  | ||||
| class AdminRadioSelect(forms.RadioSelect): | ||||
|     renderer = AdminRadioFieldRenderer | ||||
| @@ -197,7 +197,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget): | ||||
|             # The related object is registered with the same AdminSite | ||||
|             attrs['class'] = 'vManyToManyRawIdAdminField' | ||||
|         if value: | ||||
|             value = ','.join([force_unicode(v) for v in value]) | ||||
|             value = ','.join([force_text(v) for v in value]) | ||||
|         else: | ||||
|             value = '' | ||||
|         return super(ManyToManyRawIdWidget, self).render(name, value, attrs) | ||||
| @@ -221,7 +221,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget): | ||||
|         if len(initial) != len(data): | ||||
|             return True | ||||
|         for pk1, pk2 in zip(initial, data): | ||||
|             if force_unicode(pk1) != force_unicode(pk2): | ||||
|             if force_text(pk1) != force_text(pk2): | ||||
|                 return True | ||||
|         return False | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,7 @@ from email.errors import HeaderParseError | ||||
|  | ||||
| from django.utils.safestring import mark_safe | ||||
| from django.core.urlresolvers import reverse | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.encoding import smart_bytes | ||||
| try: | ||||
|     import docutils.core | ||||
|     import docutils.nodes | ||||
| @@ -66,7 +66,7 @@ def parse_rst(text, default_reference_context, thing_being_parsed=None): | ||||
|         "link_base" : reverse('django-admindocs-docroot').rstrip('/') | ||||
|     } | ||||
|     if thing_being_parsed: | ||||
|         thing_being_parsed = smart_str("<%s>" % thing_being_parsed) | ||||
|         thing_being_parsed = smart_bytes("<%s>" % thing_being_parsed) | ||||
|     parts = docutils.core.publish_parts(text, source_path=thing_being_parsed, | ||||
|                 destination_path=None, writer_name='html', | ||||
|                 settings_overrides=overrides) | ||||
|   | ||||
| @@ -14,6 +14,7 @@ from django.core import urlresolvers | ||||
| from django.contrib.admindocs import utils | ||||
| from django.contrib.sites.models import Site | ||||
| from django.utils.importlib import import_module | ||||
| from django.utils import six | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.utils.safestring import mark_safe | ||||
|  | ||||
| @@ -48,7 +49,7 @@ def template_tag_index(request): | ||||
|     load_all_installed_template_libraries() | ||||
|  | ||||
|     tags = [] | ||||
|     app_libs = template.libraries.items() | ||||
|     app_libs = list(six.iteritems(template.libraries)) | ||||
|     builtin_libs = [(None, lib) for lib in template.builtins] | ||||
|     for module_name, library in builtin_libs + app_libs: | ||||
|         for tag_name, tag_func in library.tags.items(): | ||||
| @@ -83,7 +84,7 @@ def template_filter_index(request): | ||||
|     load_all_installed_template_libraries() | ||||
|  | ||||
|     filters = [] | ||||
|     app_libs = template.libraries.items() | ||||
|     app_libs = list(six.iteritems(template.libraries)) | ||||
|     builtin_libs = [(None, lib) for lib in template.builtins] | ||||
|     for module_name, library in builtin_libs + app_libs: | ||||
|         for filter_name, filter_func in library.filters.items(): | ||||
|   | ||||
| @@ -12,6 +12,7 @@ from django.template.response import TemplateResponse | ||||
| from django.utils.html import escape | ||||
| from django.utils.decorators import method_decorator | ||||
| from django.utils.safestring import mark_safe | ||||
| from django.utils import six | ||||
| from django.utils.translation import ugettext, ugettext_lazy as _ | ||||
| from django.views.decorators.csrf import csrf_protect | ||||
| from django.views.decorators.debug import sensitive_post_parameters | ||||
| @@ -128,7 +129,7 @@ class UserAdmin(admin.ModelAdmin): | ||||
|         else: | ||||
|             form = self.change_password_form(user) | ||||
|  | ||||
|         fieldsets = [(None, {'fields': form.base_fields.keys()})] | ||||
|         fieldsets = [(None, {'fields': list(form.base_fields)})] | ||||
|         adminForm = admin.helpers.AdminForm(form, fieldsets, {}) | ||||
|  | ||||
|         context = { | ||||
|   | ||||
| @@ -11,8 +11,9 @@ class PermLookupDict(object): | ||||
|     def __getitem__(self, perm_name): | ||||
|         return self.user.has_perm("%s.%s" % (self.module_name, perm_name)) | ||||
|  | ||||
|     def __nonzero__(self): | ||||
|     def __bool__(self): | ||||
|         return self.user.has_module_perms(self.module_name) | ||||
|     __nonzero__ = __bool__ # Python 2 | ||||
|  | ||||
|  | ||||
| class PermWrapper(object): | ||||
|   | ||||
| @@ -89,9 +89,9 @@ class UserCreationForm(forms.ModelForm): | ||||
|         raise forms.ValidationError(self.error_messages['duplicate_username']) | ||||
|  | ||||
|     def clean_password2(self): | ||||
|         password1 = self.cleaned_data.get("password1", "") | ||||
|         password2 = self.cleaned_data["password2"] | ||||
|         if password1 != password2: | ||||
|         password1 = self.cleaned_data.get("password1") | ||||
|         password2 = self.cleaned_data.get("password2") | ||||
|         if password1 and password2 and password1 != password2: | ||||
|             raise forms.ValidationError( | ||||
|                 self.error_messages['password_mismatch']) | ||||
|         return password2 | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import base64 | ||||
| import hashlib | ||||
|  | ||||
| from django.dispatch import receiver | ||||
| @@ -7,7 +8,7 @@ from django.conf import settings | ||||
| from django.test.signals import setting_changed | ||||
| from django.utils import importlib | ||||
| from django.utils.datastructures import SortedDict | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.encoding import smart_bytes | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.utils.crypto import ( | ||||
|     pbkdf2, constant_time_compare, get_random_string) | ||||
| @@ -218,7 +219,7 @@ class PBKDF2PasswordHasher(BasePasswordHasher): | ||||
|         if not iterations: | ||||
|             iterations = self.iterations | ||||
|         hash = pbkdf2(password, salt, iterations, digest=self.digest) | ||||
|         hash = hash.encode('base64').strip() | ||||
|         hash = base64.b64encode(hash).strip() | ||||
|         return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash) | ||||
|  | ||||
|     def verify(self, password, encoded): | ||||
| @@ -298,7 +299,7 @@ class SHA1PasswordHasher(BasePasswordHasher): | ||||
|     def encode(self, password, salt): | ||||
|         assert password | ||||
|         assert salt and '$' not in salt | ||||
|         hash = hashlib.sha1(smart_str(salt + password)).hexdigest() | ||||
|         hash = hashlib.sha1(smart_bytes(salt + password)).hexdigest() | ||||
|         return "%s$%s$%s" % (self.algorithm, salt, hash) | ||||
|  | ||||
|     def verify(self, password, encoded): | ||||
| @@ -326,7 +327,7 @@ class MD5PasswordHasher(BasePasswordHasher): | ||||
|     def encode(self, password, salt): | ||||
|         assert password | ||||
|         assert salt and '$' not in salt | ||||
|         hash = hashlib.md5(smart_str(salt + password)).hexdigest() | ||||
|         hash = hashlib.md5(smart_bytes(salt + password)).hexdigest() | ||||
|         return "%s$%s$%s" % (self.algorithm, salt, hash) | ||||
|  | ||||
|     def verify(self, password, encoded): | ||||
| @@ -360,7 +361,7 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher): | ||||
|         return '' | ||||
|  | ||||
|     def encode(self, password, salt): | ||||
|         return hashlib.md5(smart_str(password)).hexdigest() | ||||
|         return hashlib.md5(smart_bytes(password)).hexdigest() | ||||
|  | ||||
|     def verify(self, password, encoded): | ||||
|         encoded_2 = self.encode(password, '') | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import unicodedata | ||||
| from django.contrib.auth import models as auth_app | ||||
| from django.db.models import get_models, signals | ||||
| from django.contrib.auth.models import User | ||||
| from django.utils.six.moves import input | ||||
|  | ||||
|  | ||||
| def _get_permission_codename(action, opts): | ||||
| @@ -66,10 +67,10 @@ def create_superuser(app, created_models, verbosity, db, **kwargs): | ||||
|         msg = ("\nYou just installed Django's auth system, which means you " | ||||
|             "don't have any superusers defined.\nWould you like to create one " | ||||
|             "now? (yes/no): ") | ||||
|         confirm = raw_input(msg) | ||||
|         confirm = input(msg) | ||||
|         while 1: | ||||
|             if confirm not in ('yes', 'no'): | ||||
|                 confirm = raw_input('Please enter either "yes" or "no": ') | ||||
|                 confirm = input('Please enter either "yes" or "no": ') | ||||
|                 continue | ||||
|             if confirm == 'yes': | ||||
|                 call_command("createsuperuser", interactive=True, database=db) | ||||
|   | ||||
| @@ -12,6 +12,7 @@ from django.contrib.auth.management import get_default_username | ||||
| from django.core import exceptions | ||||
| from django.core.management.base import BaseCommand, CommandError | ||||
| from django.db import DEFAULT_DB_ALIAS | ||||
| from django.utils.six.moves import input | ||||
| from django.utils.translation import ugettext as _ | ||||
|  | ||||
| RE_VALID_USERNAME = re.compile('[\w.@+-]+$') | ||||
| @@ -76,7 +77,7 @@ class Command(BaseCommand): | ||||
|                         input_msg = 'Username' | ||||
|                         if default_username: | ||||
|                             input_msg += ' (leave blank to use %r)' % default_username | ||||
|                         username = raw_input(input_msg + ': ') | ||||
|                         username = input(input_msg + ': ') | ||||
|                     if default_username and username == '': | ||||
|                         username = default_username | ||||
|                     if not RE_VALID_USERNAME.match(username): | ||||
| @@ -94,7 +95,7 @@ class Command(BaseCommand): | ||||
|                 # Get an email | ||||
|                 while 1: | ||||
|                     if not email: | ||||
|                         email = raw_input('E-mail address: ') | ||||
|                         email = input('E-mail address: ') | ||||
|                     try: | ||||
|                         is_valid_email(email) | ||||
|                     except exceptions.ValidationError: | ||||
|   | ||||
| @@ -8,7 +8,8 @@ from django.core import mail | ||||
| from django.forms.fields import Field, EmailField | ||||
| from django.test import TestCase | ||||
| from django.test.utils import override_settings | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils import six | ||||
| from django.utils import translation | ||||
| from django.utils.translation import ugettext as _ | ||||
|  | ||||
| @@ -27,7 +28,7 @@ class UserCreationFormTest(TestCase): | ||||
|         form = UserCreationForm(data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form["username"].errors, | ||||
|                          [force_unicode(form.error_messages['duplicate_username'])]) | ||||
|                          [force_text(form.error_messages['duplicate_username'])]) | ||||
|  | ||||
|     def test_invalid_data(self): | ||||
|         data = { | ||||
| @@ -38,7 +39,7 @@ class UserCreationFormTest(TestCase): | ||||
|         form = UserCreationForm(data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form["username"].errors, | ||||
|                          [force_unicode(form.fields['username'].error_messages['invalid'])]) | ||||
|                          [force_text(form.fields['username'].error_messages['invalid'])]) | ||||
|  | ||||
|     def test_password_verification(self): | ||||
|         # The verification password is incorrect. | ||||
| @@ -50,13 +51,13 @@ class UserCreationFormTest(TestCase): | ||||
|         form = UserCreationForm(data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form["password2"].errors, | ||||
|                          [force_unicode(form.error_messages['password_mismatch'])]) | ||||
|                          [force_text(form.error_messages['password_mismatch'])]) | ||||
|  | ||||
|     def test_both_passwords(self): | ||||
|         # One (or both) passwords weren't given | ||||
|         data = {'username': 'jsmith'} | ||||
|         form = UserCreationForm(data) | ||||
|         required_error = [force_unicode(Field.default_error_messages['required'])] | ||||
|         required_error = [force_text(Field.default_error_messages['required'])] | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form['password1'].errors, required_error) | ||||
|         self.assertEqual(form['password2'].errors, required_error) | ||||
| @@ -65,6 +66,7 @@ class UserCreationFormTest(TestCase): | ||||
|         form = UserCreationForm(data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form['password1'].errors, required_error) | ||||
|         self.assertEqual(form['password2'].errors, []) | ||||
|  | ||||
|     def test_success(self): | ||||
|         # The success case. | ||||
| @@ -94,7 +96,7 @@ class AuthenticationFormTest(TestCase): | ||||
|         form = AuthenticationForm(None, data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form.non_field_errors(), | ||||
|                          [force_unicode(form.error_messages['invalid_login'])]) | ||||
|                          [force_text(form.error_messages['invalid_login'])]) | ||||
|  | ||||
|     def test_inactive_user(self): | ||||
|         # The user is inactive. | ||||
| @@ -105,7 +107,7 @@ class AuthenticationFormTest(TestCase): | ||||
|         form = AuthenticationForm(None, data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form.non_field_errors(), | ||||
|                          [force_unicode(form.error_messages['inactive'])]) | ||||
|                          [force_text(form.error_messages['inactive'])]) | ||||
|  | ||||
|     def test_inactive_user_i18n(self): | ||||
|         with self.settings(USE_I18N=True): | ||||
| @@ -118,7 +120,7 @@ class AuthenticationFormTest(TestCase): | ||||
|                 form = AuthenticationForm(None, data) | ||||
|                 self.assertFalse(form.is_valid()) | ||||
|                 self.assertEqual(form.non_field_errors(), | ||||
|                                  [force_unicode(form.error_messages['inactive'])]) | ||||
|                                  [force_text(form.error_messages['inactive'])]) | ||||
|  | ||||
|     def test_success(self): | ||||
|         # The success case | ||||
| @@ -146,7 +148,7 @@ class SetPasswordFormTest(TestCase): | ||||
|         form = SetPasswordForm(user, data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form["new_password2"].errors, | ||||
|                          [force_unicode(form.error_messages['password_mismatch'])]) | ||||
|                          [force_text(form.error_messages['password_mismatch'])]) | ||||
|  | ||||
|     def test_success(self): | ||||
|         user = User.objects.get(username='testclient') | ||||
| @@ -173,7 +175,7 @@ class PasswordChangeFormTest(TestCase): | ||||
|         form = PasswordChangeForm(user, data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form["old_password"].errors, | ||||
|                          [force_unicode(form.error_messages['password_incorrect'])]) | ||||
|                          [force_text(form.error_messages['password_incorrect'])]) | ||||
|  | ||||
|     def test_password_verification(self): | ||||
|         # The two new passwords do not match. | ||||
| @@ -186,7 +188,7 @@ class PasswordChangeFormTest(TestCase): | ||||
|         form = PasswordChangeForm(user, data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form["new_password2"].errors, | ||||
|                          [force_unicode(form.error_messages['password_mismatch'])]) | ||||
|                          [force_text(form.error_messages['password_mismatch'])]) | ||||
|  | ||||
|     def test_success(self): | ||||
|         # The success case. | ||||
| @@ -202,7 +204,7 @@ class PasswordChangeFormTest(TestCase): | ||||
|     def test_field_order(self): | ||||
|         # Regression test - check the order of fields: | ||||
|         user = User.objects.get(username='testclient') | ||||
|         self.assertEqual(PasswordChangeForm(user, {}).fields.keys(), | ||||
|         self.assertEqual(list(PasswordChangeForm(user, {}).fields), | ||||
|                          ['old_password', 'new_password1', 'new_password2']) | ||||
|  | ||||
|  | ||||
| @@ -217,7 +219,7 @@ class UserChangeFormTest(TestCase): | ||||
|         form = UserChangeForm(data, instance=user) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form['username'].errors, | ||||
|                          [force_unicode(form.fields['username'].error_messages['invalid'])]) | ||||
|                          [force_text(form.fields['username'].error_messages['invalid'])]) | ||||
|  | ||||
|     def test_bug_14242(self): | ||||
|         # A regression test, introduce by adding an optimization for the | ||||
| @@ -272,7 +274,7 @@ class PasswordResetFormTest(TestCase): | ||||
|         form = PasswordResetForm(data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form['email'].errors, | ||||
|                          [force_unicode(EmailField.default_error_messages['invalid'])]) | ||||
|                          [force_text(EmailField.default_error_messages['invalid'])]) | ||||
|  | ||||
|     def test_nonexistant_email(self): | ||||
|         # Test nonexistant email address | ||||
| @@ -280,7 +282,7 @@ class PasswordResetFormTest(TestCase): | ||||
|         form = PasswordResetForm(data) | ||||
|         self.assertFalse(form.is_valid()) | ||||
|         self.assertEqual(form.errors, | ||||
|                          {'email': [force_unicode(form.error_messages['unknown'])]}) | ||||
|                          {'email': [force_text(form.error_messages['unknown'])]}) | ||||
|  | ||||
|     def test_cleaned_data(self): | ||||
|         # Regression test | ||||
|   | ||||
| @@ -7,7 +7,7 @@ from django.contrib.auth.models import User | ||||
| from django.core import mail | ||||
| from django.core.urlresolvers import reverse, NoReverseMatch | ||||
| from django.http import QueryDict | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils.html import escape | ||||
| from django.utils.http import urlquote | ||||
| from django.test import TestCase | ||||
| @@ -46,7 +46,7 @@ class AuthViewsTestCase(TestCase): | ||||
|         self.assertTrue(SESSION_KEY in self.client.session) | ||||
|  | ||||
|     def assertContainsEscaped(self, response, text, **kwargs): | ||||
|         return self.assertContains(response, escape(force_unicode(text)), **kwargs) | ||||
|         return self.assertContains(response, escape(force_text(text)), **kwargs) | ||||
|  | ||||
|  | ||||
| class AuthViewNamedURLTests(AuthViewsTestCase): | ||||
|   | ||||
| @@ -5,7 +5,7 @@ from django.conf import settings | ||||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.contrib.comments.models import Comment | ||||
| from django.utils.crypto import salted_hmac, constant_time_compare | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils.text import get_text_list | ||||
| from django.utils import timezone | ||||
| from django.utils.translation import ungettext, ugettext, ugettext_lazy as _ | ||||
| @@ -133,7 +133,7 @@ class CommentDetailsForm(CommentSecurityForm): | ||||
|         """ | ||||
|         return dict( | ||||
|             content_type = ContentType.objects.get_for_model(self.target_object), | ||||
|             object_pk    = force_unicode(self.target_object._get_pk_val()), | ||||
|             object_pk    = force_text(self.target_object._get_pk_val()), | ||||
|             user_name    = self.cleaned_data["name"], | ||||
|             user_email   = self.cleaned_data["email"], | ||||
|             user_url     = self.cleaned_data["url"], | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| from django.db import models | ||||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
|  | ||||
| class CommentManager(models.Manager): | ||||
|  | ||||
| @@ -18,5 +18,5 @@ class CommentManager(models.Manager): | ||||
|         ct = ContentType.objects.get_for_model(model) | ||||
|         qs = self.get_query_set().filter(content_type=ct) | ||||
|         if isinstance(model, models.Model): | ||||
|             qs = qs.filter(object_pk=force_unicode(model._get_pk_val())) | ||||
|             qs = qs.filter(object_pk=force_text(model._get_pk_val())) | ||||
|         return qs | ||||
|   | ||||
| @@ -3,7 +3,7 @@ from django.template.loader import render_to_string | ||||
| from django.conf import settings | ||||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.contrib import comments | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
|  | ||||
| register = template.Library() | ||||
|  | ||||
| @@ -75,7 +75,7 @@ class BaseCommentNode(template.Node): | ||||
|  | ||||
|         qs = self.comment_model.objects.filter( | ||||
|             content_type = ctype, | ||||
|             object_pk    = smart_unicode(object_pk), | ||||
|             object_pk    = smart_text(object_pk), | ||||
|             site__pk     = settings.SITE_ID, | ||||
|         ) | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ from django.forms import ModelForm | ||||
| from django.forms.models import BaseModelFormSet, modelformset_factory, save_instance | ||||
| from django.contrib.admin.options import InlineModelAdmin, flatten_fieldsets | ||||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
|  | ||||
| class GenericForeignKey(object): | ||||
|     """ | ||||
| @@ -169,7 +169,7 @@ class GenericRelation(RelatedField, Field): | ||||
|  | ||||
|     def value_to_string(self, obj): | ||||
|         qs = getattr(obj, self.name).all() | ||||
|         return smart_unicode([instance._get_pk_val() for instance in qs]) | ||||
|         return smart_text([instance._get_pk_val() for instance in qs]) | ||||
|  | ||||
|     def m2m_db_table(self): | ||||
|         return self.rel.to._meta.db_table | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| from django.contrib.contenttypes.models import ContentType | ||||
| from django.db.models import get_apps, get_models, signals | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils import six | ||||
| from django.utils.six.moves import input | ||||
|  | ||||
| def update_contenttypes(app, created_models, verbosity=2, **kwargs): | ||||
|     """ | ||||
| @@ -24,17 +26,17 @@ def update_contenttypes(app, created_models, verbosity=2, **kwargs): | ||||
|     ) | ||||
|     to_remove = [ | ||||
|         ct | ||||
|         for (model_name, ct) in content_types.iteritems() | ||||
|         for (model_name, ct) in six.iteritems(content_types) | ||||
|         if model_name not in app_models | ||||
|     ] | ||||
|  | ||||
|     cts = ContentType.objects.bulk_create([ | ||||
|         ContentType( | ||||
|             name=smart_unicode(model._meta.verbose_name_raw), | ||||
|             name=smart_text(model._meta.verbose_name_raw), | ||||
|             app_label=app_label, | ||||
|             model=model_name, | ||||
|         ) | ||||
|         for (model_name, model) in app_models.iteritems() | ||||
|         for (model_name, model) in six.iteritems(app_models) | ||||
|         if model_name not in content_types | ||||
|     ]) | ||||
|     if verbosity >= 2: | ||||
| @@ -48,7 +50,7 @@ def update_contenttypes(app, created_models, verbosity=2, **kwargs): | ||||
|                 '    %s | %s' % (ct.app_label, ct.model) | ||||
|                 for ct in to_remove | ||||
|             ]) | ||||
|             ok_to_delete = raw_input("""The following content types are stale and need to be deleted: | ||||
|             ok_to_delete = input("""The following content types are stale and need to be deleted: | ||||
|  | ||||
| %s | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| from django.db import models | ||||
| 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 | ||||
|  | ||||
| class ContentTypeManager(models.Manager): | ||||
|  | ||||
| @@ -37,13 +37,13 @@ class ContentTypeManager(models.Manager): | ||||
|         try: | ||||
|             ct = self._get_from_cache(opts) | ||||
|         except KeyError: | ||||
|             # Load or create the ContentType entry. The smart_unicode() is | ||||
|             # Load or create the ContentType entry. The smart_text() is | ||||
|             # needed around opts.verbose_name_raw because name_raw might be a | ||||
|             # django.utils.functional.__proxy__ object. | ||||
|             ct, created = self.get_or_create( | ||||
|                 app_label = opts.app_label, | ||||
|                 model = opts.object_name.lower(), | ||||
|                 defaults = {'name': smart_unicode(opts.verbose_name_raw)}, | ||||
|                 defaults = {'name': smart_text(opts.verbose_name_raw)}, | ||||
|             ) | ||||
|             self._add_to_cache(self.db, ct) | ||||
|  | ||||
| @@ -86,7 +86,7 @@ class ContentTypeManager(models.Manager): | ||||
|             ct = self.create( | ||||
|                 app_label=opts.app_label, | ||||
|                 model=opts.object_name.lower(), | ||||
|                 name=smart_unicode(opts.verbose_name_raw), | ||||
|                 name=smart_text(opts.verbose_name_raw), | ||||
|             ) | ||||
|             self._add_to_cache(self.db, ct) | ||||
|             results[ct.model_class()] = ct | ||||
| @@ -147,7 +147,7 @@ class ContentType(models.Model): | ||||
|         if not model or self.name != model._meta.verbose_name_raw: | ||||
|             return self.name | ||||
|         else: | ||||
|             return force_unicode(model._meta.verbose_name) | ||||
|             return force_text(model._meta.verbose_name) | ||||
|  | ||||
|     def model_class(self): | ||||
|         "Returns the Python model class for this type of content." | ||||
|   | ||||
| @@ -7,7 +7,7 @@ from __future__ import unicode_literals | ||||
| from django.db import models | ||||
| from django.utils import formats | ||||
| from django.utils.text import capfirst | ||||
| from django.utils.encoding import smart_unicode, smart_str, iri_to_uri | ||||
| from django.utils.encoding import smart_text, smart_bytes, iri_to_uri | ||||
| from django.db.models.query import QuerySet | ||||
|  | ||||
| EMPTY_VALUE = '(None)' | ||||
| @@ -17,12 +17,12 @@ class EasyModel(object): | ||||
|     def __init__(self, site, model): | ||||
|         self.site = site | ||||
|         self.model = model | ||||
|         self.model_list = site.registry.keys() | ||||
|         self.model_list = list(site.registry.keys()) | ||||
|         self.verbose_name = model._meta.verbose_name | ||||
|         self.verbose_name_plural = model._meta.verbose_name_plural | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return '<EasyModel for %s>' % smart_str(self.model._meta.object_name) | ||||
|         return '<EasyModel for %s>' % smart_bytes(self.model._meta.object_name) | ||||
|  | ||||
|     def model_databrowse(self): | ||||
|         "Returns the ModelDatabrowse class for this model." | ||||
| @@ -61,7 +61,7 @@ class EasyField(object): | ||||
|         self.model, self.field = easy_model, field | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return smart_str('<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)) | ||||
|         return smart_bytes('<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)) | ||||
|  | ||||
|     def choices(self): | ||||
|         for value, label in self.field.choices: | ||||
| @@ -79,7 +79,7 @@ class EasyChoice(object): | ||||
|         self.value, self.label = value, label | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return smart_str('<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name)) | ||||
|         return smart_bytes('<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name)) | ||||
|  | ||||
|     def url(self): | ||||
|         return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, iri_to_uri(self.value)) | ||||
| @@ -89,10 +89,10 @@ class EasyInstance(object): | ||||
|         self.model, self.instance = easy_model, instance | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return smart_str('<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val())) | ||||
|         return smart_bytes('<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val())) | ||||
|  | ||||
|     def __unicode__(self): | ||||
|         val = smart_unicode(self.instance) | ||||
|         val = smart_text(self.instance) | ||||
|         if len(val) > DISPLAY_SIZE: | ||||
|             return val[:DISPLAY_SIZE] + '...' | ||||
|         return val | ||||
| @@ -136,7 +136,7 @@ class EasyInstanceField(object): | ||||
|         self.raw_value = getattr(instance.instance, field.name) | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return smart_str('<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)) | ||||
|         return smart_bytes('<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)) | ||||
|  | ||||
|     def values(self): | ||||
|         """ | ||||
| @@ -176,8 +176,6 @@ class EasyInstanceField(object): | ||||
|         for plugin_name, plugin in self.model.model_databrowse().plugins.items(): | ||||
|             urls = plugin.urls(plugin_name, self) | ||||
|             if urls is not None: | ||||
|                 #plugin_urls.append(urls) | ||||
|                 values = self.values() | ||||
|                 return zip(self.values(), urls) | ||||
|         if self.field.rel: | ||||
|             m = EasyModel(self.model.site, self.field.rel.to) | ||||
| @@ -187,7 +185,7 @@ class EasyInstanceField(object): | ||||
|                     if value is None: | ||||
|                         continue | ||||
|                     url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, iri_to_uri(value._get_pk_val())) | ||||
|                     lst.append((smart_unicode(value), url)) | ||||
|                     lst.append((smart_text(value), url)) | ||||
|             else: | ||||
|                 lst = [(value, None) for value in self.values()] | ||||
|         elif self.field.choices: | ||||
| @@ -196,10 +194,10 @@ class EasyInstanceField(object): | ||||
|                 url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, iri_to_uri(self.raw_value)) | ||||
|                 lst.append((value, url)) | ||||
|         elif isinstance(self.field, models.URLField): | ||||
|             val = self.values()[0] | ||||
|             val = list(self.values())[0] | ||||
|             lst = [(val, iri_to_uri(val))] | ||||
|         else: | ||||
|             lst = [(self.values()[0], None)] | ||||
|             lst = [(list(self.values())[0], None)] | ||||
|         return lst | ||||
|  | ||||
| class EasyQuerySet(QuerySet): | ||||
|   | ||||
| @@ -7,7 +7,7 @@ from django.contrib.databrowse.sites import DatabrowsePlugin | ||||
| from django.shortcuts import render_to_response | ||||
| from django.utils.html import format_html, format_html_join | ||||
| from django.utils.text import capfirst | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.views.generic import dates | ||||
| from django.utils import datetime_safe | ||||
|  | ||||
| @@ -66,7 +66,7 @@ class CalendarPlugin(DatabrowsePlugin): | ||||
|             return '' | ||||
|         return format_html('<p class="filter"><strong>View calendar by:</strong> {0}</p>', | ||||
|                            format_html_join(', ', '<a href="calendars/{0}/">{1}</a>', | ||||
|                                             ((f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()))) | ||||
|                                             ((f.name, force_text(capfirst(f.verbose_name))) for f in fields.values()))) | ||||
|  | ||||
|     def urls(self, plugin_name, easy_instance_field): | ||||
|         if isinstance(easy_instance_field.field, models.DateField): | ||||
| @@ -96,7 +96,7 @@ class CalendarPlugin(DatabrowsePlugin): | ||||
|  | ||||
|     def homepage_view(self, request): | ||||
|         easy_model = EasyModel(self.site, self.model) | ||||
|         field_list = self.fields.values() | ||||
|         field_list = list(self.fields.values()) | ||||
|         field_list.sort(key=lambda k:k.verbose_name) | ||||
|         return render_to_response('databrowse/calendar_homepage.html', { | ||||
|                 'root_url': self.site.root_url, | ||||
|   | ||||
| @@ -8,7 +8,7 @@ from django.shortcuts import render_to_response | ||||
| from django.utils.html import format_html, format_html_join | ||||
| from django.utils.http import urlquote | ||||
| from django.utils.text import capfirst | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
|  | ||||
|  | ||||
| class FieldChoicePlugin(DatabrowsePlugin): | ||||
| @@ -35,7 +35,7 @@ class FieldChoicePlugin(DatabrowsePlugin): | ||||
|             return '' | ||||
|         return format_html('<p class="filter"><strong>View by:</strong> {0}</p>', | ||||
|                            format_html_join(', ', '<a href="fields/{0}/">{1}</a>', | ||||
|                                             ((f.name, force_unicode(capfirst(f.verbose_name))) for f in fields.values()))) | ||||
|                                             ((f.name, force_text(capfirst(f.verbose_name))) for f in fields.values()))) | ||||
|  | ||||
|     def urls(self, plugin_name, easy_instance_field): | ||||
|         if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values(): | ||||
| @@ -63,7 +63,7 @@ class FieldChoicePlugin(DatabrowsePlugin): | ||||
|  | ||||
|     def homepage_view(self, request): | ||||
|         easy_model = EasyModel(self.site, self.model) | ||||
|         field_list = self.fields.values() | ||||
|         field_list = list(self.fields.values()) | ||||
|         field_list.sort(key=lambda k: k.verbose_name) | ||||
|         return render_to_response('databrowse/fieldchoice_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list}) | ||||
|  | ||||
|   | ||||
| @@ -317,7 +317,7 @@ class WizardTests(TestCase): | ||||
|  | ||||
|         class WizardWithProcessStep(TestWizardClass): | ||||
|             def process_step(self, request, form, step): | ||||
|                 that.assertTrue(hasattr(form, 'cleaned_data')) | ||||
|                 that.assertTrue(form.is_valid()) | ||||
|                 reached[0] = True | ||||
|  | ||||
|         wizard = WizardWithProcessStep([WizardPageOneForm, | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| from django.core.files.uploadedfile import UploadedFile | ||||
| from django.utils.datastructures import MultiValueDict | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.encoding import smart_bytes | ||||
| from django.utils.functional import lazy_property | ||||
| from django.utils import six | ||||
|  | ||||
| from django.contrib.formtools.wizard.storage.exceptions import NoFileStorageConfigured | ||||
|  | ||||
| @@ -72,9 +73,9 @@ class BaseStorage(object): | ||||
|             raise NoFileStorageConfigured | ||||
|  | ||||
|         files = {} | ||||
|         for field, field_dict in wizard_files.iteritems(): | ||||
|             field_dict = dict((smart_str(k), v) | ||||
|                               for k, v in field_dict.iteritems()) | ||||
|         for field, field_dict in six.iteritems(wizard_files): | ||||
|             field_dict = dict((smart_bytes(k), v) | ||||
|                               for k, v in six.iteritems(field_dict)) | ||||
|             tmp_name = field_dict.pop('tmp_name') | ||||
|             files[field] = UploadedFile( | ||||
|                 file=self.file_storage.open(tmp_name), **field_dict) | ||||
| @@ -87,7 +88,7 @@ class BaseStorage(object): | ||||
|         if step not in self.data[self.step_files_key]: | ||||
|             self.data[self.step_files_key][step] = {} | ||||
|  | ||||
|         for field, field_file in (files or {}).iteritems(): | ||||
|         for field, field_file in six.iteritems(files or {}): | ||||
|             tmp_filename = self.file_storage.save(field_file.name, field_file) | ||||
|             file_dict = { | ||||
|                 'tmp_name': tmp_filename, | ||||
|   | ||||
| @@ -44,7 +44,7 @@ class StepsHelper(object): | ||||
|     @property | ||||
|     def all(self): | ||||
|         "Returns the names of all steps/forms." | ||||
|         return self._wizard.get_form_list().keys() | ||||
|         return list(self._wizard.get_form_list()) | ||||
|  | ||||
|     @property | ||||
|     def count(self): | ||||
| @@ -164,14 +164,14 @@ class WizardView(TemplateView): | ||||
|                 init_form_list[six.text_type(i)] = form | ||||
|  | ||||
|         # walk through the new created list of forms | ||||
|         for form in init_form_list.itervalues(): | ||||
|         for form in six.itervalues(init_form_list): | ||||
|             if issubclass(form, formsets.BaseFormSet): | ||||
|                 # if the element is based on BaseFormSet (FormSet/ModelFormSet) | ||||
|                 # we need to override the form variable. | ||||
|                 form = form.form | ||||
|             # check if any form contains a FileField, if yes, we need a | ||||
|             # file_storage added to the wizardview (by subclassing). | ||||
|             for field in form.base_fields.itervalues(): | ||||
|             for field in six.itervalues(form.base_fields): | ||||
|                 if (isinstance(field, forms.FileField) and | ||||
|                         not hasattr(cls, 'file_storage')): | ||||
|                     raise NoFileStorageConfigured | ||||
| @@ -196,7 +196,7 @@ class WizardView(TemplateView): | ||||
|         could use data from other (maybe previous forms). | ||||
|         """ | ||||
|         form_list = SortedDict() | ||||
|         for form_key, form_class in self.form_list.iteritems(): | ||||
|         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. | ||||
|             condition = self.condition_dict.get(form_key, True) | ||||
|   | ||||
| @@ -3,6 +3,8 @@ from django.db.backends.mysql.base import DatabaseOperations | ||||
| from django.contrib.gis.db.backends.adapter import WKTAdapter | ||||
| from django.contrib.gis.db.backends.base import BaseSpatialOperations | ||||
|  | ||||
| from django.utils import six | ||||
|  | ||||
| class MySQLOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|  | ||||
|     compiler_module = 'django.contrib.gis.db.backends.mysql.compiler' | ||||
| @@ -30,7 +32,7 @@ class MySQLOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|         'within' : 'MBRWithin', | ||||
|         } | ||||
|  | ||||
|     gis_terms = dict([(term, None) for term in geometry_functions.keys() + ['isnull']]) | ||||
|     gis_terms = dict([(term, None) for term in list(geometry_functions) + ['isnull']]) | ||||
|  | ||||
|     def geo_db_type(self, f): | ||||
|         return f.geom_type | ||||
|   | ||||
| @@ -128,7 +128,7 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|     geometry_functions.update(distance_functions) | ||||
|  | ||||
|     gis_terms = ['isnull'] | ||||
|     gis_terms += geometry_functions.keys() | ||||
|     gis_terms += list(geometry_functions) | ||||
|     gis_terms = dict([(term, None) for term in gis_terms]) | ||||
|  | ||||
|     truncate_params = {'relate' : None} | ||||
|   | ||||
| @@ -163,7 +163,9 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|             'contains' : PostGISFunction(prefix, 'Contains'), | ||||
|             'intersects' : PostGISFunction(prefix, 'Intersects'), | ||||
|             'relate' : (PostGISRelate, six.string_types), | ||||
|             } | ||||
|             'coveredby' : PostGISFunction(prefix, 'CoveredBy'), | ||||
|             'covers' : PostGISFunction(prefix, 'Covers'), | ||||
|         } | ||||
|  | ||||
|         # Valid distance types and substitutions | ||||
|         dtypes = (Decimal, Distance, float) + six.integer_types | ||||
| @@ -178,33 +180,12 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|             'distance_gte' : (get_dist_ops('>='), dtypes), | ||||
|             'distance_lt' : (get_dist_ops('<'), dtypes), | ||||
|             'distance_lte' : (get_dist_ops('<='), dtypes), | ||||
|             } | ||||
|  | ||||
|         # Versions 1.2.2+ have KML serialization support. | ||||
|         if version < (1, 2, 2): | ||||
|             ASKML = False | ||||
|         else: | ||||
|             ASKML = 'ST_AsKML' | ||||
|             self.geometry_functions.update( | ||||
|                 {'coveredby' : PostGISFunction(prefix, 'CoveredBy'), | ||||
|                  'covers' : PostGISFunction(prefix, 'Covers'), | ||||
|                  }) | ||||
|             self.distance_functions['dwithin'] = (PostGISFunctionParam(prefix, 'DWithin'), dtypes) | ||||
|             'dwithin' : (PostGISFunctionParam(prefix, 'DWithin'), dtypes) | ||||
|         } | ||||
|  | ||||
|         # Adding the distance functions to the geometries lookup. | ||||
|         self.geometry_functions.update(self.distance_functions) | ||||
|  | ||||
|         # The union aggregate and topology operation use the same signature | ||||
|         # in versions 1.3+. | ||||
|         if version < (1, 3, 0): | ||||
|             UNIONAGG = 'GeomUnion' | ||||
|             UNION = 'Union' | ||||
|             MAKELINE = False | ||||
|         else: | ||||
|             UNIONAGG = 'ST_Union' | ||||
|             UNION = 'ST_Union' | ||||
|             MAKELINE = 'ST_MakeLine' | ||||
|  | ||||
|         # Only PostGIS versions 1.3.4+ have GeoJSON serialization support. | ||||
|         if version < (1, 3, 4): | ||||
|             GEOJSON = False | ||||
| @@ -236,8 +217,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|  | ||||
|         # Creating a dictionary lookup of all GIS terms for PostGIS. | ||||
|         gis_terms = ['isnull'] | ||||
|         gis_terms += self.geometry_operators.keys() | ||||
|         gis_terms += self.geometry_functions.keys() | ||||
|         gis_terms += list(self.geometry_operators) | ||||
|         gis_terms += list(self.geometry_functions) | ||||
|         self.gis_terms = dict([(term, None) for term in gis_terms]) | ||||
|  | ||||
|         self.area = prefix + 'Area' | ||||
| @@ -256,11 +237,11 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|         self.geojson = GEOJSON | ||||
|         self.gml = prefix + 'AsGML' | ||||
|         self.intersection = prefix + 'Intersection' | ||||
|         self.kml = ASKML | ||||
|         self.kml = prefix + 'AsKML' | ||||
|         self.length = prefix + 'Length' | ||||
|         self.length3d = prefix + 'Length3D' | ||||
|         self.length_spheroid = prefix + 'length_spheroid' | ||||
|         self.makeline = MAKELINE | ||||
|         self.makeline = prefix + 'MakeLine' | ||||
|         self.mem_size = prefix + 'mem_size' | ||||
|         self.num_geom = prefix + 'NumGeometries' | ||||
|         self.num_points =prefix + 'npoints' | ||||
| @@ -275,8 +256,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|         self.sym_difference = prefix + 'SymDifference' | ||||
|         self.transform = prefix + 'Transform' | ||||
|         self.translate = prefix + 'Translate' | ||||
|         self.union = UNION | ||||
|         self.unionagg = UNIONAGG | ||||
|         self.union = prefix + 'Union' | ||||
|         self.unionagg = prefix + 'Union' | ||||
|  | ||||
|     def check_aggregate_support(self, aggregate): | ||||
|         """ | ||||
|   | ||||
| @@ -99,14 +99,14 @@ class SpatiaLiteCreation(DatabaseCreation): | ||||
|         """ | ||||
|         This routine loads up the SpatiaLite SQL file. | ||||
|         """ | ||||
|         if self.connection.ops.spatial_version[:2] >= (3, 0): | ||||
|             # Spatialite >= 3.0.x -- No need to load any SQL file, calling | ||||
|         if self.connection.ops.spatial_version[:2] >= (2, 4): | ||||
|             # Spatialite >= 2.4 -- No need to load any SQL file, calling | ||||
|             # InitSpatialMetaData() transparently creates the spatial metadata | ||||
|             # tables | ||||
|             cur = self.connection._cursor() | ||||
|             cur.execute("SELECT InitSpatialMetaData()") | ||||
|         else: | ||||
|             # Spatialite < 3.0.x -- Load the initial SQL | ||||
|             # Spatialite < 2.4 -- Load the initial SQL | ||||
|  | ||||
|             # Getting the location of the SpatiaLite SQL file, and confirming | ||||
|             # it exists. | ||||
|   | ||||
| @@ -131,7 +131,7 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations): | ||||
|  | ||||
|         # Creating the GIS terms dictionary. | ||||
|         gis_terms = ['isnull'] | ||||
|         gis_terms += self.geometry_functions.keys() | ||||
|         gis_terms += list(self.geometry_functions) | ||||
|         self.gis_terms = dict([(term, None) for term in gis_terms]) | ||||
|  | ||||
|         if version >= (2, 4, 0): | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| from django.db import connections | ||||
| from django.db.models.query import QuerySet, ValuesQuerySet, ValuesListQuerySet | ||||
| from django.utils import six | ||||
|  | ||||
| from django.contrib.gis.db.models import aggregates | ||||
| from django.contrib.gis.db.models.fields import get_srid_info, PointField, LineStringField | ||||
| @@ -25,7 +26,7 @@ class GeoQuerySet(QuerySet): | ||||
|         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=GeoValuesListQuerySet, setup=True, flat=flat, | ||||
| @@ -531,7 +532,7 @@ class GeoQuerySet(QuerySet): | ||||
|         if settings.get('setup', True): | ||||
|             default_args, geo_field = self._spatial_setup(att, desc=settings['desc'], field_name=field_name, | ||||
|                                                           geo_field_type=settings.get('geo_field_type', None)) | ||||
|             for k, v in default_args.iteritems(): settings['procedure_args'].setdefault(k, v) | ||||
|             for k, v in six.iteritems(default_args): settings['procedure_args'].setdefault(k, v) | ||||
|         else: | ||||
|             geo_field = settings['geo_field'] | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ from django.utils.six.moves import zip | ||||
| from django.db.backends.util import truncate_name, typecast_timestamp | ||||
| from django.db.models.sql import compiler | ||||
| from django.db.models.sql.constants import MULTI | ||||
| from django.utils import six | ||||
|  | ||||
| SQLCompiler = compiler.SQLCompiler | ||||
|  | ||||
| @@ -24,7 +25,7 @@ class GeoSQLCompiler(compiler.SQLCompiler): | ||||
|         qn = self.quote_name_unless_alias | ||||
|         qn2 = self.connection.ops.quote_name | ||||
|         result = ['(%s) AS %s' % (self.get_extra_select_format(alias) % col[0], qn2(alias)) | ||||
|                   for alias, col in self.query.extra_select.iteritems()] | ||||
|                   for alias, col in six.iteritems(self.query.extra_select)] | ||||
|         aliases = set(self.query.extra_select.keys()) | ||||
|         if with_aliases: | ||||
|             col_aliases = aliases.copy() | ||||
| @@ -170,7 +171,7 @@ class GeoSQLCompiler(compiler.SQLCompiler): | ||||
|         objects. | ||||
|         """ | ||||
|         values = [] | ||||
|         aliases = self.query.extra_select.keys() | ||||
|         aliases = list(self.query.extra_select) | ||||
|  | ||||
|         # Have to set a starting row number offset that is used for | ||||
|         # determining the correct starting row index -- needed for | ||||
|   | ||||
| @@ -40,7 +40,7 @@ | ||||
| """ | ||||
| # Python library requisites. | ||||
| import sys | ||||
| from binascii import a2b_hex | ||||
| from binascii import a2b_hex, b2a_hex | ||||
| from ctypes import byref, string_at, c_char_p, c_double, c_ubyte, c_void_p | ||||
|  | ||||
| # Getting GDAL prerequisites | ||||
| @@ -322,8 +322,7 @@ class OGRGeometry(GDALBase): | ||||
|     @property | ||||
|     def hex(self): | ||||
|         "Returns the hexadecimal representation of the WKB (a string)." | ||||
|         return str(self.wkb).encode('hex').upper() | ||||
|         #return b2a_hex(self.wkb).upper() | ||||
|         return b2a_hex(self.wkb).upper() | ||||
|  | ||||
|     @property | ||||
|     def json(self): | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import json | ||||
| import os | ||||
|  | ||||
| from django.contrib import gis | ||||
| from django.utils import six | ||||
|  | ||||
|  | ||||
| # This global used to store reference geometry data. | ||||
| @@ -25,7 +26,7 @@ def tuplize(seq): | ||||
|  | ||||
| def strconvert(d): | ||||
|     "Converts all keys in dictionary to str type." | ||||
|     return dict([(str(k), v) for k, v in d.iteritems()]) | ||||
|     return dict([(str(k), v) for k, v in six.iteritems(d)]) | ||||
|  | ||||
|  | ||||
| def get_ds_file(name, ext): | ||||
|   | ||||
| @@ -143,7 +143,7 @@ class MeasureBase(object): | ||||
|     def __rmul__(self, other): | ||||
|         return self * other | ||||
|  | ||||
|     def __div__(self, other): | ||||
|     def __truediv__(self, other): | ||||
|         if isinstance(other, self.__class__): | ||||
|             return self.standard / other.standard | ||||
|         if isinstance(other, NUMERIC_TYPES): | ||||
| @@ -151,16 +151,19 @@ class MeasureBase(object): | ||||
|                 **{self.STANDARD_UNIT: (self.standard / other)}) | ||||
|         else: | ||||
|             raise TypeError('%(class)s must be divided with number or %(class)s' % {"class":pretty_name(self)}) | ||||
|     __div__ = __truediv__ # Python 2 compatibility | ||||
|  | ||||
|     def __idiv__(self, other): | ||||
|     def __itruediv__(self, other): | ||||
|         if isinstance(other, NUMERIC_TYPES): | ||||
|             self.standard /= float(other) | ||||
|             return self | ||||
|         else: | ||||
|             raise TypeError('%(class)s must be divided with number' % {"class":pretty_name(self)}) | ||||
|     __idiv__ = __itruediv__ # Python 2 compatibility | ||||
|  | ||||
|     def __nonzero__(self): | ||||
|     def __bool__(self): | ||||
|         return bool(self.standard) | ||||
|     __nonzero__ = __bool__ # Python 2 compatibility | ||||
|  | ||||
|     def default_units(self, kwargs): | ||||
|         """ | ||||
| @@ -169,7 +172,7 @@ class MeasureBase(object): | ||||
|         """ | ||||
|         val = 0.0 | ||||
|         default_unit = self.STANDARD_UNIT | ||||
|         for unit, value in kwargs.iteritems(): | ||||
|         for unit, value in six.iteritems(kwargs): | ||||
|             if not isinstance(value, float): value = float(value) | ||||
|             if unit in self.UNITS: | ||||
|                 val += self.UNITS[unit] * value | ||||
| @@ -305,12 +308,13 @@ class Area(MeasureBase): | ||||
|     ALIAS = dict([(k, '%s%s' % (AREA_PREFIX, v)) for k, v in Distance.ALIAS.items()]) | ||||
|     LALIAS = dict([(k.lower(), v) for k, v in ALIAS.items()]) | ||||
|  | ||||
|     def __div__(self, other): | ||||
|     def __truediv__(self, other): | ||||
|         if isinstance(other, NUMERIC_TYPES): | ||||
|             return self.__class__(default_unit=self._default_unit, | ||||
|                 **{self.STANDARD_UNIT: (self.standard / other)}) | ||||
|         else: | ||||
|             raise TypeError('%(class)s must be divided by a number' % {"class":pretty_name(self)}) | ||||
|     __div__ = __truediv__ # Python 2 compatibility | ||||
|  | ||||
|  | ||||
| # Shortcuts | ||||
|   | ||||
| @@ -8,7 +8,8 @@ from django.core.paginator import EmptyPage, PageNotAnInteger | ||||
| from django.contrib.gis.db.models.fields import GeometryField | ||||
| from django.db import connections, DEFAULT_DB_ALIAS | ||||
| from django.db.models import get_model | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.encoding import smart_bytes | ||||
| from django.utils import six | ||||
| from django.utils.translation import ugettext as _ | ||||
|  | ||||
| from django.contrib.gis.shortcuts import render_to_kml, render_to_kmz | ||||
| @@ -46,7 +47,7 @@ def sitemap(request, sitemaps, section=None): | ||||
|             raise Http404(_("No sitemap available for section: %r") % section) | ||||
|         maps.append(sitemaps[section]) | ||||
|     else: | ||||
|         maps = sitemaps.values() | ||||
|         maps = list(six.itervalues(sitemaps)) | ||||
|  | ||||
|     page = request.GET.get("p", 1) | ||||
|     current_site = get_current_site(request) | ||||
| @@ -60,7 +61,7 @@ def sitemap(request, sitemaps, section=None): | ||||
|             raise Http404(_("Page %s empty") % page) | ||||
|         except PageNotAnInteger: | ||||
|             raise Http404(_("No page '%s'") % page) | ||||
|     xml = smart_str(loader.render_to_string('gis/sitemaps/geo_sitemap.xml', {'urlset': urls})) | ||||
|     xml = smart_bytes(loader.render_to_string('gis/sitemaps/geo_sitemap.xml', {'urlset': urls})) | ||||
|     return HttpResponse(xml, content_type='application/xml') | ||||
|  | ||||
| def kml(request, label, model, field_name=None, compress=False, using=DEFAULT_DB_ALIAS): | ||||
|   | ||||
| @@ -12,7 +12,7 @@ from .models import City, PennsylvaniaCity, State, Truth | ||||
|  | ||||
| class GeoRegressionTests(TestCase): | ||||
|  | ||||
|     def test01_update(self): | ||||
|     def test_update(self): | ||||
|         "Testing GeoQuerySet.update(). See #10411." | ||||
|         pnt = City.objects.get(name='Pueblo').point | ||||
|         bak = pnt.clone() | ||||
| @@ -24,7 +24,7 @@ class GeoRegressionTests(TestCase): | ||||
|         City.objects.filter(name='Pueblo').update(point=bak) | ||||
|         self.assertEqual(bak, City.objects.get(name='Pueblo').point) | ||||
|  | ||||
|     def test02_kmz(self): | ||||
|     def test_kmz(self): | ||||
|         "Testing `render_to_kmz` with non-ASCII data. See #11624." | ||||
|         name = '\xc3\x85land Islands'.decode('iso-8859-1') | ||||
|         places = [{'name' : name, | ||||
| @@ -35,7 +35,7 @@ class GeoRegressionTests(TestCase): | ||||
|  | ||||
|     @no_spatialite | ||||
|     @no_mysql | ||||
|     def test03_extent(self): | ||||
|     def test_extent(self): | ||||
|         "Testing `extent` on a table with a single point. See #11827." | ||||
|         pnt = City.objects.get(name='Pueblo').point | ||||
|         ref_ext = (pnt.x, pnt.y, pnt.x, pnt.y) | ||||
| @@ -43,14 +43,14 @@ class GeoRegressionTests(TestCase): | ||||
|         for ref_val, val in zip(ref_ext, extent): | ||||
|             self.assertAlmostEqual(ref_val, val, 4) | ||||
|  | ||||
|     def test04_unicode_date(self): | ||||
|     def test_unicode_date(self): | ||||
|         "Testing dates are converted properly, even on SpatiaLite. See #16408." | ||||
|         founded = datetime(1857, 5, 23) | ||||
|         mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)', | ||||
|                                                     founded=founded) | ||||
|         self.assertEqual(founded, PennsylvaniaCity.objects.dates('founded', 'day')[0]) | ||||
|  | ||||
|     def test05_empty_count(self): | ||||
|     def test_empty_count(self): | ||||
|          "Testing that PostGISAdapter.__eq__ does check empty strings. See #13670." | ||||
|          # contrived example, but need a geo lookup paired with an id__in lookup | ||||
|          pueblo = City.objects.get(name='Pueblo') | ||||
| @@ -60,12 +60,12 @@ class GeoRegressionTests(TestCase): | ||||
|          # .count() should not throw TypeError in __eq__ | ||||
|          self.assertEqual(cities_within_state.count(), 1) | ||||
|  | ||||
|     def test06_defer_or_only_with_annotate(self): | ||||
|     def test_defer_or_only_with_annotate(self): | ||||
|         "Regression for #16409. Make sure defer() and only() work with annotate()" | ||||
|         self.assertIsInstance(list(City.objects.annotate(Count('point')).defer('name')), list) | ||||
|         self.assertIsInstance(list(City.objects.annotate(Count('point')).only('name')), list) | ||||
|  | ||||
|     def test07_boolean_conversion(self): | ||||
|     def test_boolean_conversion(self): | ||||
|         "Testing Boolean value conversion with the spatial backend, see #15169." | ||||
|         t1 = Truth.objects.create(val=True) | ||||
|         t2 = Truth.objects.create(val=False) | ||||
|   | ||||
| @@ -15,19 +15,24 @@ from django.utils import six | ||||
|  | ||||
| from .models import Country, City, PennsylvaniaCity, State, Track | ||||
|  | ||||
| from .test_feeds import GeoFeedTest | ||||
| from .test_regress import GeoRegressionTests | ||||
| from .test_sitemaps import GeoSitemapTest | ||||
|  | ||||
|  | ||||
| if not spatialite: | ||||
|     from .models import Feature, MinusOneSRID | ||||
|  | ||||
| class GeoModelTest(TestCase): | ||||
|  | ||||
|     def test01_fixtures(self): | ||||
|     def test_fixtures(self): | ||||
|         "Testing geographic model initialization from fixtures." | ||||
|         # Ensuring that data was loaded from initial data fixtures. | ||||
|         self.assertEqual(2, Country.objects.count()) | ||||
|         self.assertEqual(8, City.objects.count()) | ||||
|         self.assertEqual(2, State.objects.count()) | ||||
|  | ||||
|     def test02_proxy(self): | ||||
|     def test_proxy(self): | ||||
|         "Testing Lazy-Geometry support (using the GeometryProxy)." | ||||
|         ## Testing on a Point | ||||
|         pnt = Point(0, 0) | ||||
| @@ -95,165 +100,97 @@ class GeoModelTest(TestCase): | ||||
|         self.assertEqual(ply, State.objects.get(name='NullState').poly) | ||||
|         ns.delete() | ||||
|  | ||||
|     def test03a_kml(self): | ||||
|         "Testing KML output from the database using GeoQuerySet.kml()." | ||||
|         # Only PostGIS and Spatialite (>=2.4.0-RC4) support KML serialization | ||||
|         if not (postgis or (spatialite and connection.ops.kml)): | ||||
|             self.assertRaises(NotImplementedError, State.objects.all().kml, field_name='poly') | ||||
|             return | ||||
|  | ||||
|         # Should throw a TypeError when trying to obtain KML from a | ||||
|         #  non-geometry field. | ||||
|         qs = City.objects.all() | ||||
|         self.assertRaises(TypeError, qs.kml, 'name') | ||||
|  | ||||
|         # The reference KML depends on the version of PostGIS used | ||||
|         # (the output stopped including altitude in 1.3.3). | ||||
|         if connection.ops.spatial_version >= (1, 3, 3): | ||||
|             ref_kml =  '<Point><coordinates>-104.609252,38.255001</coordinates></Point>' | ||||
|         else: | ||||
|             ref_kml = '<Point><coordinates>-104.609252,38.255001,0</coordinates></Point>' | ||||
|  | ||||
|         # Ensuring the KML is as expected. | ||||
|         ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo') | ||||
|         ptown2 = City.objects.kml(precision=9).get(name='Pueblo') | ||||
|         for ptown in [ptown1, ptown2]: | ||||
|             self.assertEqual(ref_kml, ptown.kml) | ||||
|  | ||||
|     def test03b_gml(self): | ||||
|         "Testing GML output from the database using GeoQuerySet.gml()." | ||||
|         if mysql or (spatialite and not connection.ops.gml) : | ||||
|             self.assertRaises(NotImplementedError, Country.objects.all().gml, field_name='mpoly') | ||||
|             return | ||||
|  | ||||
|         # Should throw a TypeError when tyring to obtain GML from a | ||||
|         # non-geometry field. | ||||
|         qs = City.objects.all() | ||||
|         self.assertRaises(TypeError, qs.gml, field_name='name') | ||||
|         ptown1 = City.objects.gml(field_name='point', precision=9).get(name='Pueblo') | ||||
|         ptown2 = City.objects.gml(precision=9).get(name='Pueblo') | ||||
|     @no_mysql | ||||
|     def test_lookup_insert_transform(self): | ||||
|         "Testing automatic transform for lookups and inserts." | ||||
|         # San Antonio in 'WGS84' (SRID 4326) | ||||
|         sa_4326 = 'POINT (-98.493183 29.424170)' | ||||
|         wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84 | ||||
|  | ||||
|         # Oracle doesn't have SRID 3084, using 41157. | ||||
|         if oracle: | ||||
|             # No precision parameter for Oracle :-/ | ||||
|             gml_regex = re.compile(r'^<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ </gml:coordinates></gml:Point>') | ||||
|         elif spatialite: | ||||
|             # Spatialite has extra colon in SrsName | ||||
|             gml_regex = re.compile(r'^<gml:Point SrsName="EPSG::4326"><gml:coordinates decimal="\." cs="," ts=" ">-104.609251\d+,38.255001</gml:coordinates></gml:Point>') | ||||
|             # San Antonio in 'Texas 4205, Southern Zone (1983, meters)' (SRID 41157) | ||||
|             # Used the following Oracle SQL to get this value: | ||||
|             #  SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_CS.TRANSFORM(SDO_GEOMETRY('POINT (-98.493183 29.424170)', 4326), 41157)) FROM DUAL; | ||||
|             nad_wkt  = 'POINT (300662.034646583 5416427.45974934)' | ||||
|             nad_srid = 41157 | ||||
|         else: | ||||
|             gml_regex = re.compile(r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>-104\.60925\d+,38\.255001</gml:coordinates></gml:Point>') | ||||
|             # San Antonio in 'NAD83(HARN) / Texas Centric Lambert Conformal' (SRID 3084) | ||||
|             nad_wkt = 'POINT (1645978.362408288754523 6276356.025927528738976)' # Used ogr.py in gdal 1.4.1 for this transform | ||||
|             nad_srid = 3084 | ||||
|  | ||||
|         for ptown in [ptown1, ptown2]: | ||||
|             self.assertTrue(gml_regex.match(ptown.gml)) | ||||
|  | ||||
|  | ||||
|     def test03c_geojson(self): | ||||
|         "Testing GeoJSON output from the database using GeoQuerySet.geojson()." | ||||
|         # Only PostGIS 1.3.4+ supports GeoJSON. | ||||
|         if not connection.ops.geojson: | ||||
|             self.assertRaises(NotImplementedError, Country.objects.all().geojson, field_name='mpoly') | ||||
|             return | ||||
|  | ||||
|         if connection.ops.spatial_version >= (1, 4, 0): | ||||
|             pueblo_json = '{"type":"Point","coordinates":[-104.609252,38.255001]}' | ||||
|             houston_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}' | ||||
|             victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.305196,48.462611]}' | ||||
|             chicago_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}' | ||||
|         # Constructing & querying with a point from a different SRID. Oracle | ||||
|         # `SDO_OVERLAPBDYINTERSECT` operates differently from | ||||
|         # `ST_Intersects`, so contains is used instead. | ||||
|         nad_pnt = fromstr(nad_wkt, srid=nad_srid) | ||||
|         if oracle: | ||||
|             tx = Country.objects.get(mpoly__contains=nad_pnt) | ||||
|         else: | ||||
|             pueblo_json = '{"type":"Point","coordinates":[-104.60925200,38.25500100]}' | ||||
|             houston_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"coordinates":[-95.36315100,29.76337400]}' | ||||
|             victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.30519600,48.46261100]}' | ||||
|             chicago_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}' | ||||
|             tx = Country.objects.get(mpoly__intersects=nad_pnt) | ||||
|         self.assertEqual('Texas', tx.name) | ||||
|  | ||||
|         # Precision argument should only be an integer | ||||
|         self.assertRaises(TypeError, City.objects.geojson, precision='foo') | ||||
|         # Creating San Antonio.  Remember the Alamo. | ||||
|         sa = City.objects.create(name='San Antonio', point=nad_pnt) | ||||
|  | ||||
|         # Reference queries and values. | ||||
|         # SELECT ST_AsGeoJson("geoapp_city"."point", 8, 0) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Pueblo'; | ||||
|         self.assertEqual(pueblo_json, City.objects.geojson().get(name='Pueblo').geojson) | ||||
|         # Now verifying that San Antonio was transformed correctly | ||||
|         sa = City.objects.get(name='San Antonio') | ||||
|         self.assertAlmostEqual(wgs_pnt.x, sa.point.x, 6) | ||||
|         self.assertAlmostEqual(wgs_pnt.y, sa.point.y, 6) | ||||
|  | ||||
|         # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; | ||||
|         # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; | ||||
|         # This time we want to include the CRS by using the `crs` keyword. | ||||
|         self.assertEqual(houston_json, City.objects.geojson(crs=True, model_att='json').get(name='Houston').json) | ||||
|         # If the GeometryField SRID is -1, then we shouldn't perform any | ||||
|         # transformation if the SRID of the input geometry is different. | ||||
|         # SpatiaLite does not support missing SRID values. | ||||
|         if not spatialite: | ||||
|             m1 = MinusOneSRID(geom=Point(17, 23, srid=4326)) | ||||
|             m1.save() | ||||
|             self.assertEqual(-1, m1.geom.srid) | ||||
|  | ||||
|         # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Victoria'; | ||||
|         # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; | ||||
|         # This time we include the bounding box by using the `bbox` keyword. | ||||
|         self.assertEqual(victoria_json, City.objects.geojson(bbox=True).get(name='Victoria').geojson) | ||||
|     def test_createnull(self): | ||||
|         "Testing creating a model instance and the geometry being None" | ||||
|         c = City() | ||||
|         self.assertEqual(c.point, None) | ||||
|  | ||||
|         # 1.(3|4).x: SELECT ST_AsGeoJson("geoapp_city"."point", 5, 3) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Chicago'; | ||||
|         # Finally, we set every available keyword. | ||||
|         self.assertEqual(chicago_json, City.objects.geojson(bbox=True, crs=True, precision=5).get(name='Chicago').geojson) | ||||
|     @no_spatialite # SpatiaLite does not support abstract geometry columns | ||||
|     def test_geometryfield(self): | ||||
|         "Testing the general GeometryField." | ||||
|         Feature(name='Point', geom=Point(1, 1)).save() | ||||
|         Feature(name='LineString', geom=LineString((0, 0), (1, 1), (5, 5))).save() | ||||
|         Feature(name='Polygon', geom=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)))).save() | ||||
|         Feature(name='GeometryCollection', | ||||
|                 geom=GeometryCollection(Point(2, 2), LineString((0, 0), (2, 2)), | ||||
|                                         Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))).save() | ||||
|  | ||||
|     def test03d_svg(self): | ||||
|         "Testing SVG output using GeoQuerySet.svg()." | ||||
|         if mysql or oracle: | ||||
|             self.assertRaises(NotImplementedError, City.objects.svg) | ||||
|             return | ||||
|         f_1 = Feature.objects.get(name='Point') | ||||
|         self.assertEqual(True, isinstance(f_1.geom, Point)) | ||||
|         self.assertEqual((1.0, 1.0), f_1.geom.tuple) | ||||
|         f_2 = Feature.objects.get(name='LineString') | ||||
|         self.assertEqual(True, isinstance(f_2.geom, LineString)) | ||||
|         self.assertEqual(((0.0, 0.0), (1.0, 1.0), (5.0, 5.0)), f_2.geom.tuple) | ||||
|  | ||||
|         self.assertRaises(TypeError, City.objects.svg, precision='foo') | ||||
|         # SELECT AsSVG(geoapp_city.point, 0, 8) FROM geoapp_city WHERE name = 'Pueblo'; | ||||
|         svg1 = 'cx="-104.609252" cy="-38.255001"' | ||||
|         # Even though relative, only one point so it's practically the same except for | ||||
|         # the 'c' letter prefix on the x,y values. | ||||
|         svg2 = svg1.replace('c', '') | ||||
|         self.assertEqual(svg1, City.objects.svg().get(name='Pueblo').svg) | ||||
|         self.assertEqual(svg2, City.objects.svg(relative=5).get(name='Pueblo').svg) | ||||
|         f_3 = Feature.objects.get(name='Polygon') | ||||
|         self.assertEqual(True, isinstance(f_3.geom, Polygon)) | ||||
|         f_4 = Feature.objects.get(name='GeometryCollection') | ||||
|         self.assertEqual(True, isinstance(f_4.geom, GeometryCollection)) | ||||
|         self.assertEqual(f_3.geom, f_4.geom[2]) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test04_transform(self): | ||||
|         "Testing the transform() GeoManager method." | ||||
|         # Pre-transformed points for Houston and Pueblo. | ||||
|         htown = fromstr('POINT(1947516.83115183 6322297.06040572)', srid=3084) | ||||
|         ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774) | ||||
|         prec = 3 # Precision is low due to version variations in PROJ and GDAL. | ||||
|     def test_inherited_geofields(self): | ||||
|         "Test GeoQuerySet methods on inherited Geometry fields." | ||||
|         # Creating a Pennsylvanian city. | ||||
|         mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)') | ||||
|  | ||||
|         # Asserting the result of the transform operation with the values in | ||||
|         #  the pre-transformed points.  Oracle does not have the 3084 SRID. | ||||
|         if not oracle: | ||||
|             h = City.objects.transform(htown.srid).get(name='Houston') | ||||
|             self.assertEqual(3084, h.point.srid) | ||||
|             self.assertAlmostEqual(htown.x, h.point.x, prec) | ||||
|             self.assertAlmostEqual(htown.y, h.point.y, prec) | ||||
|         # All transformation SQL will need to be performed on the | ||||
|         # _parent_ table. | ||||
|         qs = PennsylvaniaCity.objects.transform(32128) | ||||
|  | ||||
|         p1 = City.objects.transform(ptown.srid, field_name='point').get(name='Pueblo') | ||||
|         p2 = City.objects.transform(srid=ptown.srid).get(name='Pueblo') | ||||
|         for p in [p1, p2]: | ||||
|             self.assertEqual(2774, p.point.srid) | ||||
|             self.assertAlmostEqual(ptown.x, p.point.x, prec) | ||||
|             self.assertAlmostEqual(ptown.y, p.point.y, prec) | ||||
|         self.assertEqual(1, qs.count()) | ||||
|         for pc in qs: self.assertEqual(32128, pc.point.srid) | ||||
|  | ||||
|  | ||||
| class GeoLookupTest(TestCase): | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_spatialite # SpatiaLite does not have an Extent function | ||||
|     def test05_extent(self): | ||||
|         "Testing the `extent` GeoQuerySet method." | ||||
|         # Reference query: | ||||
|         # `SELECT ST_extent(point) FROM geoapp_city WHERE (name='Houston' or name='Dallas');` | ||||
|         #   =>  BOX(-96.8016128540039 29.7633724212646,-95.3631439208984 32.7820587158203) | ||||
|         expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820) | ||||
|  | ||||
|         qs = City.objects.filter(name__in=('Houston', 'Dallas')) | ||||
|         extent = qs.extent() | ||||
|  | ||||
|         for val, exp in zip(extent, expected): | ||||
|             self.assertAlmostEqual(exp, val, 4) | ||||
|  | ||||
|     # Only PostGIS has support for the MakeLine aggregate. | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     @no_spatialite | ||||
|     def test06_make_line(self): | ||||
|         "Testing the `make_line` GeoQuerySet method." | ||||
|         # Ensuring that a `TypeError` is raised on models without PointFields. | ||||
|         self.assertRaises(TypeError, State.objects.make_line) | ||||
|         self.assertRaises(TypeError, Country.objects.make_line) | ||||
|         # Reference query: | ||||
|         # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city; | ||||
|         ref_line = GEOSGeometry('LINESTRING(-95.363151 29.763374,-96.801611 32.782057,-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326) | ||||
|         self.assertEqual(ref_line, City.objects.make_line()) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test09_disjoint(self): | ||||
|     def test_disjoint_lookup(self): | ||||
|         "Testing the `disjoint` lookup type." | ||||
|         ptown = City.objects.get(name='Pueblo') | ||||
|         qs1 = City.objects.filter(point__disjoint=ptown.point) | ||||
| @@ -263,7 +200,7 @@ class GeoModelTest(TestCase): | ||||
|         self.assertEqual(1, qs2.count()) | ||||
|         self.assertEqual('Kansas', qs2[0].name) | ||||
|  | ||||
|     def test10_contains_contained(self): | ||||
|     def test_contains_contained_lookups(self): | ||||
|         "Testing the 'contained', 'contains', and 'bbcontains' lookup types." | ||||
|         # Getting Texas, yes we were a country -- once ;) | ||||
|         texas = Country.objects.get(name='Texas') | ||||
| @@ -308,86 +245,11 @@ class GeoModelTest(TestCase): | ||||
|             self.assertEqual(1, len(qs)) | ||||
|             self.assertEqual('Texas', qs[0].name) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test11_lookup_insert_transform(self): | ||||
|         "Testing automatic transform for lookups and inserts." | ||||
|         # San Antonio in 'WGS84' (SRID 4326) | ||||
|         sa_4326 = 'POINT (-98.493183 29.424170)' | ||||
|         wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84 | ||||
|  | ||||
|         # Oracle doesn't have SRID 3084, using 41157. | ||||
|         if oracle: | ||||
|             # San Antonio in 'Texas 4205, Southern Zone (1983, meters)' (SRID 41157) | ||||
|             # Used the following Oracle SQL to get this value: | ||||
|             #  SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_CS.TRANSFORM(SDO_GEOMETRY('POINT (-98.493183 29.424170)', 4326), 41157)) FROM DUAL; | ||||
|             nad_wkt  = 'POINT (300662.034646583 5416427.45974934)' | ||||
|             nad_srid = 41157 | ||||
|         else: | ||||
|             # San Antonio in 'NAD83(HARN) / Texas Centric Lambert Conformal' (SRID 3084) | ||||
|             nad_wkt = 'POINT (1645978.362408288754523 6276356.025927528738976)' # Used ogr.py in gdal 1.4.1 for this transform | ||||
|             nad_srid = 3084 | ||||
|  | ||||
|         # Constructing & querying with a point from a different SRID. Oracle | ||||
|         # `SDO_OVERLAPBDYINTERSECT` operates differently from | ||||
|         # `ST_Intersects`, so contains is used instead. | ||||
|         nad_pnt = fromstr(nad_wkt, srid=nad_srid) | ||||
|         if oracle: | ||||
|             tx = Country.objects.get(mpoly__contains=nad_pnt) | ||||
|         else: | ||||
|             tx = Country.objects.get(mpoly__intersects=nad_pnt) | ||||
|         self.assertEqual('Texas', tx.name) | ||||
|  | ||||
|         # Creating San Antonio.  Remember the Alamo. | ||||
|         sa = City.objects.create(name='San Antonio', point=nad_pnt) | ||||
|  | ||||
|         # Now verifying that San Antonio was transformed correctly | ||||
|         sa = City.objects.get(name='San Antonio') | ||||
|         self.assertAlmostEqual(wgs_pnt.x, sa.point.x, 6) | ||||
|         self.assertAlmostEqual(wgs_pnt.y, sa.point.y, 6) | ||||
|  | ||||
|         # If the GeometryField SRID is -1, then we shouldn't perform any | ||||
|         # transformation if the SRID of the input geometry is different. | ||||
|         # SpatiaLite does not support missing SRID values. | ||||
|         if not spatialite: | ||||
|             m1 = MinusOneSRID(geom=Point(17, 23, srid=4326)) | ||||
|             m1.save() | ||||
|             self.assertEqual(-1, m1.geom.srid) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test12_null_geometries(self): | ||||
|         "Testing NULL geometry support, and the `isnull` lookup type." | ||||
|         # Creating a state with a NULL boundary. | ||||
|         State.objects.create(name='Puerto Rico') | ||||
|  | ||||
|         # Querying for both NULL and Non-NULL values. | ||||
|         nullqs = State.objects.filter(poly__isnull=True) | ||||
|         validqs = State.objects.filter(poly__isnull=False) | ||||
|  | ||||
|         # Puerto Rico should be NULL (it's a commonwealth unincorporated territory) | ||||
|         self.assertEqual(1, len(nullqs)) | ||||
|         self.assertEqual('Puerto Rico', nullqs[0].name) | ||||
|  | ||||
|         # The valid states should be Colorado & Kansas | ||||
|         self.assertEqual(2, len(validqs)) | ||||
|         state_names = [s.name for s in validqs] | ||||
|         self.assertEqual(True, 'Colorado' in state_names) | ||||
|         self.assertEqual(True, 'Kansas' in state_names) | ||||
|  | ||||
|         # Saving another commonwealth w/a NULL geometry. | ||||
|         nmi = State.objects.create(name='Northern Mariana Islands', poly=None) | ||||
|         self.assertEqual(nmi.poly, None) | ||||
|  | ||||
|         # Assigning a geomery and saving -- then UPDATE back to NULL. | ||||
|         nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))' | ||||
|         nmi.save() | ||||
|         State.objects.filter(name='Northern Mariana Islands').update(poly=None) | ||||
|         self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly) | ||||
|  | ||||
|     # Only PostGIS has `left` and `right` lookup types. | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     @no_spatialite | ||||
|     def test13_left_right(self): | ||||
|     def test_left_right_lookups(self): | ||||
|         "Testing the 'left' and 'right' lookup types." | ||||
|         # Left: A << B => true if xmax(A) < xmin(B) | ||||
|         # Right: A >> B => true if xmin(A) > xmax(B) | ||||
| @@ -423,7 +285,7 @@ class GeoModelTest(TestCase): | ||||
|         self.assertEqual(2, len(qs)) | ||||
|         for c in qs: self.assertEqual(True, c.name in cities) | ||||
|  | ||||
|     def test14_equals(self): | ||||
|     def test_equals_lookups(self): | ||||
|         "Testing the 'same_as' and 'equals' lookup types." | ||||
|         pnt = fromstr('POINT (-95.363151 29.763374)', srid=4326) | ||||
|         c1 = City.objects.get(point=pnt) | ||||
| @@ -432,7 +294,37 @@ class GeoModelTest(TestCase): | ||||
|         for c in [c1, c2, c3]: self.assertEqual('Houston', c.name) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test15_relate(self): | ||||
|     def test_null_geometries(self): | ||||
|         "Testing NULL geometry support, and the `isnull` lookup type." | ||||
|         # Creating a state with a NULL boundary. | ||||
|         State.objects.create(name='Puerto Rico') | ||||
|  | ||||
|         # Querying for both NULL and Non-NULL values. | ||||
|         nullqs = State.objects.filter(poly__isnull=True) | ||||
|         validqs = State.objects.filter(poly__isnull=False) | ||||
|  | ||||
|         # Puerto Rico should be NULL (it's a commonwealth unincorporated territory) | ||||
|         self.assertEqual(1, len(nullqs)) | ||||
|         self.assertEqual('Puerto Rico', nullqs[0].name) | ||||
|  | ||||
|         # The valid states should be Colorado & Kansas | ||||
|         self.assertEqual(2, len(validqs)) | ||||
|         state_names = [s.name for s in validqs] | ||||
|         self.assertEqual(True, 'Colorado' in state_names) | ||||
|         self.assertEqual(True, 'Kansas' in state_names) | ||||
|  | ||||
|         # Saving another commonwealth w/a NULL geometry. | ||||
|         nmi = State.objects.create(name='Northern Mariana Islands', poly=None) | ||||
|         self.assertEqual(nmi.poly, None) | ||||
|  | ||||
|         # Assigning a geomery and saving -- then UPDATE back to NULL. | ||||
|         nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))' | ||||
|         nmi.save() | ||||
|         State.objects.filter(name='Northern Mariana Islands').update(poly=None) | ||||
|         self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test_relate_lookup(self): | ||||
|         "Testing the 'relate' lookup type." | ||||
|         # To make things more interesting, we will have our Texas reference point in | ||||
|         # different SRIDs. | ||||
| @@ -474,60 +366,12 @@ class GeoModelTest(TestCase): | ||||
|             self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, intersects_mask)).name) | ||||
|             self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, intersects_mask)).name) | ||||
|  | ||||
|     def test16_createnull(self): | ||||
|         "Testing creating a model instance and the geometry being None" | ||||
|         c = City() | ||||
|         self.assertEqual(c.point, None) | ||||
|  | ||||
| class GeoQuerySetTest(TestCase): | ||||
|     # Please keep the tests in GeoQuerySet method's alphabetic order | ||||
|  | ||||
|     @no_mysql | ||||
|     def test17_unionagg(self): | ||||
|         "Testing the `unionagg` (aggregate union) GeoManager method." | ||||
|         tx = Country.objects.get(name='Texas').mpoly | ||||
|         # Houston, Dallas -- Oracle has different order. | ||||
|         union1 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)') | ||||
|         union2 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)') | ||||
|         qs = City.objects.filter(point__within=tx) | ||||
|         self.assertRaises(TypeError, qs.unionagg, 'name') | ||||
|         # Using `field_name` keyword argument in one query and specifying an | ||||
|         # order in the other (which should not be used because this is | ||||
|         # an aggregate method on a spatial column) | ||||
|         u1 = qs.unionagg(field_name='point') | ||||
|         u2 = qs.order_by('name').unionagg() | ||||
|         tol = 0.00001 | ||||
|         if oracle: | ||||
|             union = union2 | ||||
|         else: | ||||
|             union = union1 | ||||
|         self.assertEqual(True, union.equals_exact(u1, tol)) | ||||
|         self.assertEqual(True, union.equals_exact(u2, tol)) | ||||
|         qs = City.objects.filter(name='NotACity') | ||||
|         self.assertEqual(None, qs.unionagg(field_name='point')) | ||||
|  | ||||
|     @no_spatialite # SpatiaLite does not support abstract geometry columns | ||||
|     def test18_geometryfield(self): | ||||
|         "Testing the general GeometryField." | ||||
|         Feature(name='Point', geom=Point(1, 1)).save() | ||||
|         Feature(name='LineString', geom=LineString((0, 0), (1, 1), (5, 5))).save() | ||||
|         Feature(name='Polygon', geom=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)))).save() | ||||
|         Feature(name='GeometryCollection', | ||||
|                 geom=GeometryCollection(Point(2, 2), LineString((0, 0), (2, 2)), | ||||
|                                         Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))).save() | ||||
|  | ||||
|         f_1 = Feature.objects.get(name='Point') | ||||
|         self.assertEqual(True, isinstance(f_1.geom, Point)) | ||||
|         self.assertEqual((1.0, 1.0), f_1.geom.tuple) | ||||
|         f_2 = Feature.objects.get(name='LineString') | ||||
|         self.assertEqual(True, isinstance(f_2.geom, LineString)) | ||||
|         self.assertEqual(((0.0, 0.0), (1.0, 1.0), (5.0, 5.0)), f_2.geom.tuple) | ||||
|  | ||||
|         f_3 = Feature.objects.get(name='Polygon') | ||||
|         self.assertEqual(True, isinstance(f_3.geom, Polygon)) | ||||
|         f_4 = Feature.objects.get(name='GeometryCollection') | ||||
|         self.assertEqual(True, isinstance(f_4.geom, GeometryCollection)) | ||||
|         self.assertEqual(f_3.geom, f_4.geom[2]) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test19_centroid(self): | ||||
|     def test_centroid(self): | ||||
|         "Testing the `centroid` GeoQuerySet method." | ||||
|         qs = State.objects.exclude(poly__isnull=True).centroid() | ||||
|         if oracle: | ||||
| @@ -540,84 +384,7 @@ class GeoModelTest(TestCase): | ||||
|             self.assertEqual(True, s.poly.centroid.equals_exact(s.centroid, tol)) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test20_pointonsurface(self): | ||||
|         "Testing the `point_on_surface` GeoQuerySet method." | ||||
|         # Reference values. | ||||
|         if oracle: | ||||
|             # SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_GEOM.SDO_POINTONSURFACE(GEOAPP_COUNTRY.MPOLY, 0.05)) FROM GEOAPP_COUNTRY; | ||||
|             ref = {'New Zealand' : fromstr('POINT (174.616364 -36.100861)', srid=4326), | ||||
|                    'Texas' : fromstr('POINT (-103.002434 36.500397)', srid=4326), | ||||
|                    } | ||||
|  | ||||
|         elif postgis or spatialite: | ||||
|             # Using GEOSGeometry to compute the reference point on surface values | ||||
|             # -- since PostGIS also uses GEOS these should be the same. | ||||
|             ref = {'New Zealand' : Country.objects.get(name='New Zealand').mpoly.point_on_surface, | ||||
|                    'Texas' : Country.objects.get(name='Texas').mpoly.point_on_surface | ||||
|                    } | ||||
|  | ||||
|         for c in Country.objects.point_on_surface(): | ||||
|             if spatialite: | ||||
|                 # XXX This seems to be a WKT-translation-related precision issue? | ||||
|                 tol = 0.00001 | ||||
|             else: | ||||
|                 tol = 0.000000001 | ||||
|             self.assertEqual(True, ref[c.name].equals_exact(c.point_on_surface, tol)) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     def test21_scale(self): | ||||
|         "Testing the `scale` GeoQuerySet method." | ||||
|         xfac, yfac = 2, 3 | ||||
|         tol = 5 # XXX The low precision tolerance is for SpatiaLite | ||||
|         qs = Country.objects.scale(xfac, yfac, model_att='scaled') | ||||
|         for c in qs: | ||||
|             for p1, p2 in zip(c.mpoly, c.scaled): | ||||
|                 for r1, r2 in zip(p1, p2): | ||||
|                     for c1, c2 in zip(r1.coords, r2.coords): | ||||
|                         self.assertAlmostEqual(c1[0] * xfac, c2[0], tol) | ||||
|                         self.assertAlmostEqual(c1[1] * yfac, c2[1], tol) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     def test22_translate(self): | ||||
|         "Testing the `translate` GeoQuerySet method." | ||||
|         xfac, yfac = 5, -23 | ||||
|         qs = Country.objects.translate(xfac, yfac, model_att='translated') | ||||
|         for c in qs: | ||||
|             for p1, p2 in zip(c.mpoly, c.translated): | ||||
|                 for r1, r2 in zip(p1, p2): | ||||
|                     for c1, c2 in zip(r1.coords, r2.coords): | ||||
|                         # XXX The low precision is for SpatiaLite | ||||
|                         self.assertAlmostEqual(c1[0] + xfac, c2[0], 5) | ||||
|                         self.assertAlmostEqual(c1[1] + yfac, c2[1], 5) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test23_numgeom(self): | ||||
|         "Testing the `num_geom` GeoQuerySet method." | ||||
|         # Both 'countries' only have two geometries. | ||||
|         for c in Country.objects.num_geom(): self.assertEqual(2, c.num_geom) | ||||
|         for c in City.objects.filter(point__isnull=False).num_geom(): | ||||
|             # Oracle will return 1 for the number of geometries on non-collections, | ||||
|             # whereas PostGIS will return None. | ||||
|             if postgis: | ||||
|                 self.assertEqual(None, c.num_geom) | ||||
|             else: | ||||
|                 self.assertEqual(1, c.num_geom) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_spatialite # SpatiaLite can only count vertices in LineStrings | ||||
|     def test24_numpoints(self): | ||||
|         "Testing the `num_points` GeoQuerySet method." | ||||
|         for c in Country.objects.num_points(): | ||||
|             self.assertEqual(c.mpoly.num_points, c.num_points) | ||||
|  | ||||
|         if not oracle: | ||||
|             # Oracle cannot count vertices in Point geometries. | ||||
|             for c in City.objects.num_points(): self.assertEqual(1, c.num_points) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test25_geoset(self): | ||||
|     def test_diff_intersection_union(self): | ||||
|         "Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods." | ||||
|         geom = Point(5, 23) | ||||
|         tol = 1 | ||||
| @@ -644,22 +411,232 @@ class GeoModelTest(TestCase): | ||||
|                 self.assertEqual(c.mpoly.union(geom), c.union) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test26_inherited_geofields(self): | ||||
|         "Test GeoQuerySet methods on inherited Geometry fields." | ||||
|         # Creating a Pennsylvanian city. | ||||
|         mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)') | ||||
|     @no_spatialite # SpatiaLite does not have an Extent function | ||||
|     def test_extent(self): | ||||
|         "Testing the `extent` GeoQuerySet method." | ||||
|         # Reference query: | ||||
|         # `SELECT ST_extent(point) FROM geoapp_city WHERE (name='Houston' or name='Dallas');` | ||||
|         #   =>  BOX(-96.8016128540039 29.7633724212646,-95.3631439208984 32.7820587158203) | ||||
|         expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820) | ||||
|  | ||||
|         # All transformation SQL will need to be performed on the | ||||
|         # _parent_ table. | ||||
|         qs = PennsylvaniaCity.objects.transform(32128) | ||||
|         qs = City.objects.filter(name__in=('Houston', 'Dallas')) | ||||
|         extent = qs.extent() | ||||
|  | ||||
|         self.assertEqual(1, qs.count()) | ||||
|         for pc in qs: self.assertEqual(32128, pc.point.srid) | ||||
|         for val, exp in zip(extent, expected): | ||||
|             self.assertAlmostEqual(exp, val, 4) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     @no_spatialite | ||||
|     def test27_snap_to_grid(self): | ||||
|     def test_force_rhr(self): | ||||
|         "Testing GeoQuerySet.force_rhr()." | ||||
|         rings = ( ( (0, 0), (5, 0), (0, 5), (0, 0) ), | ||||
|                   ( (1, 1), (1, 3), (3, 1), (1, 1) ), | ||||
|                   ) | ||||
|         rhr_rings = ( ( (0, 0), (0, 5), (5, 0), (0, 0) ), | ||||
|                       ( (1, 1), (3, 1), (1, 3), (1, 1) ), | ||||
|                       ) | ||||
|         State.objects.create(name='Foo', poly=Polygon(*rings)) | ||||
|         s = State.objects.force_rhr().get(name='Foo') | ||||
|         self.assertEqual(rhr_rings, s.force_rhr.coords) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     @no_spatialite | ||||
|     def test_geohash(self): | ||||
|         "Testing GeoQuerySet.geohash()." | ||||
|         if not connection.ops.geohash: return | ||||
|         # Reference query: | ||||
|         # SELECT ST_GeoHash(point) FROM geoapp_city WHERE name='Houston'; | ||||
|         # SELECT ST_GeoHash(point, 5) FROM geoapp_city WHERE name='Houston'; | ||||
|         ref_hash = '9vk1mfq8jx0c8e0386z6' | ||||
|         h1 = City.objects.geohash().get(name='Houston') | ||||
|         h2 = City.objects.geohash(precision=5).get(name='Houston') | ||||
|         self.assertEqual(ref_hash, h1.geohash) | ||||
|         self.assertEqual(ref_hash[:5], h2.geohash) | ||||
|  | ||||
|     def test_geojson(self): | ||||
|         "Testing GeoJSON output from the database using GeoQuerySet.geojson()." | ||||
|         # Only PostGIS 1.3.4+ supports GeoJSON. | ||||
|         if not connection.ops.geojson: | ||||
|             self.assertRaises(NotImplementedError, Country.objects.all().geojson, field_name='mpoly') | ||||
|             return | ||||
|  | ||||
|         if connection.ops.spatial_version >= (1, 4, 0): | ||||
|             pueblo_json = '{"type":"Point","coordinates":[-104.609252,38.255001]}' | ||||
|             houston_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}' | ||||
|             victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.305196,48.462611]}' | ||||
|             chicago_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}' | ||||
|         else: | ||||
|             pueblo_json = '{"type":"Point","coordinates":[-104.60925200,38.25500100]}' | ||||
|             houston_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"coordinates":[-95.36315100,29.76337400]}' | ||||
|             victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.30519600,48.46261100]}' | ||||
|             chicago_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}' | ||||
|  | ||||
|         # Precision argument should only be an integer | ||||
|         self.assertRaises(TypeError, City.objects.geojson, precision='foo') | ||||
|  | ||||
|         # Reference queries and values. | ||||
|         # SELECT ST_AsGeoJson("geoapp_city"."point", 8, 0) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Pueblo'; | ||||
|         self.assertEqual(pueblo_json, City.objects.geojson().get(name='Pueblo').geojson) | ||||
|  | ||||
|         # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; | ||||
|         # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; | ||||
|         # This time we want to include the CRS by using the `crs` keyword. | ||||
|         self.assertEqual(houston_json, City.objects.geojson(crs=True, model_att='json').get(name='Houston').json) | ||||
|  | ||||
|         # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Victoria'; | ||||
|         # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; | ||||
|         # This time we include the bounding box by using the `bbox` keyword. | ||||
|         self.assertEqual(victoria_json, City.objects.geojson(bbox=True).get(name='Victoria').geojson) | ||||
|  | ||||
|         # 1.(3|4).x: SELECT ST_AsGeoJson("geoapp_city"."point", 5, 3) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Chicago'; | ||||
|         # Finally, we set every available keyword. | ||||
|         self.assertEqual(chicago_json, City.objects.geojson(bbox=True, crs=True, precision=5).get(name='Chicago').geojson) | ||||
|  | ||||
|     def test_gml(self): | ||||
|         "Testing GML output from the database using GeoQuerySet.gml()." | ||||
|         if mysql or (spatialite and not connection.ops.gml) : | ||||
|             self.assertRaises(NotImplementedError, Country.objects.all().gml, field_name='mpoly') | ||||
|             return | ||||
|  | ||||
|         # Should throw a TypeError when tyring to obtain GML from a | ||||
|         # non-geometry field. | ||||
|         qs = City.objects.all() | ||||
|         self.assertRaises(TypeError, qs.gml, field_name='name') | ||||
|         ptown1 = City.objects.gml(field_name='point', precision=9).get(name='Pueblo') | ||||
|         ptown2 = City.objects.gml(precision=9).get(name='Pueblo') | ||||
|  | ||||
|         if oracle: | ||||
|             # No precision parameter for Oracle :-/ | ||||
|             gml_regex = re.compile(r'^<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ </gml:coordinates></gml:Point>') | ||||
|         elif spatialite: | ||||
|             # Spatialite has extra colon in SrsName | ||||
|             gml_regex = re.compile(r'^<gml:Point SrsName="EPSG::4326"><gml:coordinates decimal="\." cs="," ts=" ">-104.609251\d+,38.255001</gml:coordinates></gml:Point>') | ||||
|         else: | ||||
|             gml_regex = re.compile(r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>-104\.60925\d+,38\.255001</gml:coordinates></gml:Point>') | ||||
|  | ||||
|         for ptown in [ptown1, ptown2]: | ||||
|             self.assertTrue(gml_regex.match(ptown.gml)) | ||||
|  | ||||
|     def test_kml(self): | ||||
|         "Testing KML output from the database using GeoQuerySet.kml()." | ||||
|         # Only PostGIS and Spatialite (>=2.4.0-RC4) support KML serialization | ||||
|         if not (postgis or (spatialite and connection.ops.kml)): | ||||
|             self.assertRaises(NotImplementedError, State.objects.all().kml, field_name='poly') | ||||
|             return | ||||
|  | ||||
|         # Should throw a TypeError when trying to obtain KML from a | ||||
|         #  non-geometry field. | ||||
|         qs = City.objects.all() | ||||
|         self.assertRaises(TypeError, qs.kml, 'name') | ||||
|  | ||||
|         # The reference KML depends on the version of PostGIS used | ||||
|         # (the output stopped including altitude in 1.3.3). | ||||
|         if connection.ops.spatial_version >= (1, 3, 3): | ||||
|             ref_kml =  '<Point><coordinates>-104.609252,38.255001</coordinates></Point>' | ||||
|         else: | ||||
|             ref_kml = '<Point><coordinates>-104.609252,38.255001,0</coordinates></Point>' | ||||
|  | ||||
|         # Ensuring the KML is as expected. | ||||
|         ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo') | ||||
|         ptown2 = City.objects.kml(precision=9).get(name='Pueblo') | ||||
|         for ptown in [ptown1, ptown2]: | ||||
|             self.assertEqual(ref_kml, ptown.kml) | ||||
|  | ||||
|     # Only PostGIS has support for the MakeLine aggregate. | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     @no_spatialite | ||||
|     def test_make_line(self): | ||||
|         "Testing the `make_line` GeoQuerySet method." | ||||
|         # Ensuring that a `TypeError` is raised on models without PointFields. | ||||
|         self.assertRaises(TypeError, State.objects.make_line) | ||||
|         self.assertRaises(TypeError, Country.objects.make_line) | ||||
|         # Reference query: | ||||
|         # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city; | ||||
|         ref_line = GEOSGeometry('LINESTRING(-95.363151 29.763374,-96.801611 32.782057,-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326) | ||||
|         self.assertEqual(ref_line, City.objects.make_line()) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test_num_geom(self): | ||||
|         "Testing the `num_geom` GeoQuerySet method." | ||||
|         # Both 'countries' only have two geometries. | ||||
|         for c in Country.objects.num_geom(): self.assertEqual(2, c.num_geom) | ||||
|         for c in City.objects.filter(point__isnull=False).num_geom(): | ||||
|             # Oracle will return 1 for the number of geometries on non-collections, | ||||
|             # whereas PostGIS will return None. | ||||
|             if postgis: | ||||
|                 self.assertEqual(None, c.num_geom) | ||||
|             else: | ||||
|                 self.assertEqual(1, c.num_geom) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_spatialite # SpatiaLite can only count vertices in LineStrings | ||||
|     def test_num_points(self): | ||||
|         "Testing the `num_points` GeoQuerySet method." | ||||
|         for c in Country.objects.num_points(): | ||||
|             self.assertEqual(c.mpoly.num_points, c.num_points) | ||||
|  | ||||
|         if not oracle: | ||||
|             # Oracle cannot count vertices in Point geometries. | ||||
|             for c in City.objects.num_points(): self.assertEqual(1, c.num_points) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test_point_on_surface(self): | ||||
|         "Testing the `point_on_surface` GeoQuerySet method." | ||||
|         # Reference values. | ||||
|         if oracle: | ||||
|             # SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_GEOM.SDO_POINTONSURFACE(GEOAPP_COUNTRY.MPOLY, 0.05)) FROM GEOAPP_COUNTRY; | ||||
|             ref = {'New Zealand' : fromstr('POINT (174.616364 -36.100861)', srid=4326), | ||||
|                    'Texas' : fromstr('POINT (-103.002434 36.500397)', srid=4326), | ||||
|                    } | ||||
|  | ||||
|         elif postgis or spatialite: | ||||
|             # Using GEOSGeometry to compute the reference point on surface values | ||||
|             # -- since PostGIS also uses GEOS these should be the same. | ||||
|             ref = {'New Zealand' : Country.objects.get(name='New Zealand').mpoly.point_on_surface, | ||||
|                    'Texas' : Country.objects.get(name='Texas').mpoly.point_on_surface | ||||
|                    } | ||||
|  | ||||
|         for c in Country.objects.point_on_surface(): | ||||
|             if spatialite: | ||||
|                 # XXX This seems to be a WKT-translation-related precision issue? | ||||
|                 tol = 0.00001 | ||||
|             else: | ||||
|                 tol = 0.000000001 | ||||
|             self.assertEqual(True, ref[c.name].equals_exact(c.point_on_surface, tol)) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_spatialite | ||||
|     def test_reverse_geom(self): | ||||
|         "Testing GeoQuerySet.reverse_geom()." | ||||
|         coords = [ (-95.363151, 29.763374), (-95.448601, 29.713803) ] | ||||
|         Track.objects.create(name='Foo', line=LineString(coords)) | ||||
|         t = Track.objects.reverse_geom().get(name='Foo') | ||||
|         coords.reverse() | ||||
|         self.assertEqual(tuple(coords), t.reverse_geom.coords) | ||||
|         if oracle: | ||||
|             self.assertRaises(TypeError, State.objects.reverse_geom) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     def test_scale(self): | ||||
|         "Testing the `scale` GeoQuerySet method." | ||||
|         xfac, yfac = 2, 3 | ||||
|         tol = 5 # XXX The low precision tolerance is for SpatiaLite | ||||
|         qs = Country.objects.scale(xfac, yfac, model_att='scaled') | ||||
|         for c in qs: | ||||
|             for p1, p2 in zip(c.mpoly, c.scaled): | ||||
|                 for r1, r2 in zip(p1, p2): | ||||
|                     for c1, c2 in zip(r1.coords, r2.coords): | ||||
|                         self.assertAlmostEqual(c1[0] * xfac, c2[0], tol) | ||||
|                         self.assertAlmostEqual(c1[1] * yfac, c2[1], tol) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     @no_spatialite | ||||
|     def test_snap_to_grid(self): | ||||
|         "Testing GeoQuerySet.snap_to_grid()." | ||||
|         # Let's try and break snap_to_grid() with bad combinations of arguments. | ||||
|         for bad_args in ((), range(3), range(5)): | ||||
| @@ -695,48 +672,78 @@ class GeoModelTest(TestCase): | ||||
|         ref = fromstr('MULTIPOLYGON(((12.4 43.87,12.45 43.87,12.45 44.1,12.5 44.1,12.5 43.87,12.45 43.87,12.4 43.87)))') | ||||
|         self.assertTrue(ref.equals_exact(Country.objects.snap_to_grid(0.05, 0.23, 0.5, 0.17).get(name='San Marino').snap_to_grid, tol)) | ||||
|  | ||||
|     def test_svg(self): | ||||
|         "Testing SVG output using GeoQuerySet.svg()." | ||||
|         if mysql or oracle: | ||||
|             self.assertRaises(NotImplementedError, City.objects.svg) | ||||
|             return | ||||
|  | ||||
|         self.assertRaises(TypeError, City.objects.svg, precision='foo') | ||||
|         # SELECT AsSVG(geoapp_city.point, 0, 8) FROM geoapp_city WHERE name = 'Pueblo'; | ||||
|         svg1 = 'cx="-104.609252" cy="-38.255001"' | ||||
|         # Even though relative, only one point so it's practically the same except for | ||||
|         # the 'c' letter prefix on the x,y values. | ||||
|         svg2 = svg1.replace('c', '') | ||||
|         self.assertEqual(svg1, City.objects.svg().get(name='Pueblo').svg) | ||||
|         self.assertEqual(svg2, City.objects.svg(relative=5).get(name='Pueblo').svg) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_spatialite | ||||
|     def test28_reverse(self): | ||||
|         "Testing GeoQuerySet.reverse_geom()." | ||||
|         coords = [ (-95.363151, 29.763374), (-95.448601, 29.713803) ] | ||||
|         Track.objects.create(name='Foo', line=LineString(coords)) | ||||
|         t = Track.objects.reverse_geom().get(name='Foo') | ||||
|         coords.reverse() | ||||
|         self.assertEqual(tuple(coords), t.reverse_geom.coords) | ||||
|     def test_transform(self): | ||||
|         "Testing the transform() GeoQuerySet method." | ||||
|         # Pre-transformed points for Houston and Pueblo. | ||||
|         htown = fromstr('POINT(1947516.83115183 6322297.06040572)', srid=3084) | ||||
|         ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774) | ||||
|         prec = 3 # Precision is low due to version variations in PROJ and GDAL. | ||||
|  | ||||
|         # Asserting the result of the transform operation with the values in | ||||
|         #  the pre-transformed points.  Oracle does not have the 3084 SRID. | ||||
|         if not oracle: | ||||
|             h = City.objects.transform(htown.srid).get(name='Houston') | ||||
|             self.assertEqual(3084, h.point.srid) | ||||
|             self.assertAlmostEqual(htown.x, h.point.x, prec) | ||||
|             self.assertAlmostEqual(htown.y, h.point.y, prec) | ||||
|  | ||||
|         p1 = City.objects.transform(ptown.srid, field_name='point').get(name='Pueblo') | ||||
|         p2 = City.objects.transform(srid=ptown.srid).get(name='Pueblo') | ||||
|         for p in [p1, p2]: | ||||
|             self.assertEqual(2774, p.point.srid) | ||||
|             self.assertAlmostEqual(ptown.x, p.point.x, prec) | ||||
|             self.assertAlmostEqual(ptown.y, p.point.y, prec) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     def test_translate(self): | ||||
|         "Testing the `translate` GeoQuerySet method." | ||||
|         xfac, yfac = 5, -23 | ||||
|         qs = Country.objects.translate(xfac, yfac, model_att='translated') | ||||
|         for c in qs: | ||||
|             for p1, p2 in zip(c.mpoly, c.translated): | ||||
|                 for r1, r2 in zip(p1, p2): | ||||
|                     for c1, c2 in zip(r1.coords, r2.coords): | ||||
|                         # XXX The low precision is for SpatiaLite | ||||
|                         self.assertAlmostEqual(c1[0] + xfac, c2[0], 5) | ||||
|                         self.assertAlmostEqual(c1[1] + yfac, c2[1], 5) | ||||
|  | ||||
|     @no_mysql | ||||
|     def test_unionagg(self): | ||||
|         "Testing the `unionagg` (aggregate union) GeoQuerySet method." | ||||
|         tx = Country.objects.get(name='Texas').mpoly | ||||
|         # Houston, Dallas -- Oracle has different order. | ||||
|         union1 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)') | ||||
|         union2 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)') | ||||
|         qs = City.objects.filter(point__within=tx) | ||||
|         self.assertRaises(TypeError, qs.unionagg, 'name') | ||||
|         # Using `field_name` keyword argument in one query and specifying an | ||||
|         # order in the other (which should not be used because this is | ||||
|         # an aggregate method on a spatial column) | ||||
|         u1 = qs.unionagg(field_name='point') | ||||
|         u2 = qs.order_by('name').unionagg() | ||||
|         tol = 0.00001 | ||||
|         if oracle: | ||||
|             self.assertRaises(TypeError, State.objects.reverse_geom) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     @no_spatialite | ||||
|     def test29_force_rhr(self): | ||||
|         "Testing GeoQuerySet.force_rhr()." | ||||
|         rings = ( ( (0, 0), (5, 0), (0, 5), (0, 0) ), | ||||
|                   ( (1, 1), (1, 3), (3, 1), (1, 1) ), | ||||
|                   ) | ||||
|         rhr_rings = ( ( (0, 0), (0, 5), (5, 0), (0, 0) ), | ||||
|                       ( (1, 1), (3, 1), (1, 3), (1, 1) ), | ||||
|                       ) | ||||
|         State.objects.create(name='Foo', poly=Polygon(*rings)) | ||||
|         s = State.objects.force_rhr().get(name='Foo') | ||||
|         self.assertEqual(rhr_rings, s.force_rhr.coords) | ||||
|  | ||||
|     @no_mysql | ||||
|     @no_oracle | ||||
|     @no_spatialite | ||||
|     def test30_geohash(self): | ||||
|         "Testing GeoQuerySet.geohash()." | ||||
|         if not connection.ops.geohash: return | ||||
|         # Reference query: | ||||
|         # SELECT ST_GeoHash(point) FROM geoapp_city WHERE name='Houston'; | ||||
|         # SELECT ST_GeoHash(point, 5) FROM geoapp_city WHERE name='Houston'; | ||||
|         ref_hash = '9vk1mfq8jx0c8e0386z6' | ||||
|         h1 = City.objects.geohash().get(name='Houston') | ||||
|         h2 = City.objects.geohash(precision=5).get(name='Houston') | ||||
|         self.assertEqual(ref_hash, h1.geohash) | ||||
|         self.assertEqual(ref_hash[:5], h2.geohash) | ||||
|  | ||||
| from .test_feeds import GeoFeedTest | ||||
| from .test_regress import GeoRegressionTests | ||||
| from .test_sitemaps import GeoSitemapTest | ||||
|             union = union2 | ||||
|         else: | ||||
|             union = union1 | ||||
|         self.assertEqual(True, union.equals_exact(u1, tol)) | ||||
|         self.assertEqual(True, union.equals_exact(u2, tol)) | ||||
|         qs = City.objects.filter(name='NotACity') | ||||
|         self.assertEqual(None, qs.unionagg(field_name='point')) | ||||
|   | ||||
| @@ -5,7 +5,7 @@ from datetime import date, datetime | ||||
| from django import template | ||||
| from django.conf import settings | ||||
| from django.template import defaultfilters | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils.formats import number_format | ||||
| from django.utils.translation import pgettext, ungettext, ugettext as _ | ||||
| from django.utils.timezone import is_aware, utc | ||||
| @@ -41,7 +41,7 @@ def intcomma(value, use_l10n=True): | ||||
|             return intcomma(value, False) | ||||
|         else: | ||||
|             return number_format(value, force_grouping=True) | ||||
|     orig = force_unicode(value) | ||||
|     orig = force_text(value) | ||||
|     new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', orig) | ||||
|     if orig == new: | ||||
|         return new | ||||
|   | ||||
| @@ -10,7 +10,7 @@ from django.contrib.localflavor.au.au_states import STATE_CHOICES | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, RegexField, Select | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -44,7 +44,7 @@ class AUPhoneNumberField(Field): | ||||
|         super(AUPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = re.sub('(\(|\)|\s+|-)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\(|\)|\s+|-)', '', smart_text(value)) | ||||
|         phone_match = PHONE_DIGITS_RE.search(value) | ||||
|         if phone_match: | ||||
|             return '%s' % phone_match.group(1) | ||||
|   | ||||
| @@ -11,7 +11,7 @@ from django.contrib.localflavor.br.br_states import STATE_CHOICES | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, RegexField, CharField, Select | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -35,7 +35,7 @@ class BRPhoneNumberField(Field): | ||||
|         super(BRPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = re.sub('(\(|\)|\s+)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\(|\)|\s+)', '', smart_text(value)) | ||||
|         m = phone_digits_re.search(value) | ||||
|         if m: | ||||
|             return '%s-%s-%s' % (m.group(1), m.group(2), m.group(3)) | ||||
| @@ -68,10 +68,10 @@ class BRStateChoiceField(Field): | ||||
|         value = super(BRStateChoiceField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             value = '' | ||||
|         value = smart_unicode(value) | ||||
|         value = smart_text(value) | ||||
|         if value == '': | ||||
|             return value | ||||
|         valid_values = set([smart_unicode(k) for k, v in self.widget.choices]) | ||||
|         valid_values = set([smart_text(k) for k, v in self.widget.choices]) | ||||
|         if value not in valid_values: | ||||
|             raise ValidationError(self.error_messages['invalid']) | ||||
|         return value | ||||
| @@ -154,10 +154,10 @@ class BRCNPJField(Field): | ||||
|             raise ValidationError(self.error_messages['max_digits']) | ||||
|         orig_dv = value[-2:] | ||||
|  | ||||
|         new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))]) | ||||
|         new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(list(range(5, 1, -1)) + list(range(9, 1, -1)))]) | ||||
|         new_1dv = DV_maker(new_1dv % 11) | ||||
|         value = value[:-2] + str(new_1dv) + value[-1] | ||||
|         new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(6, 1, -1) + range(9, 1, -1))]) | ||||
|         new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(list(range(6, 1, -1)) + list(range(9, 1, -1)))]) | ||||
|         new_2dv = DV_maker(new_2dv % 11) | ||||
|         value = value[:-1] + str(new_2dv) | ||||
|         if value[-2:] != orig_dv: | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import re | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, CharField, Select | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -53,7 +53,7 @@ class CAPhoneNumberField(Field): | ||||
|         super(CAPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = re.sub('(\(|\)|\s+)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\(|\)|\s+)', '', smart_text(value)) | ||||
|         m = phone_digits_re.search(value) | ||||
|         if m: | ||||
|             return '%s-%s-%s' % (m.group(1), m.group(2), m.group(3)) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ from django.contrib.localflavor.ch.ch_states import STATE_CHOICES | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, RegexField, Select | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -41,7 +41,7 @@ class CHPhoneNumberField(Field): | ||||
|         super(CHPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = re.sub('(\.|\s|/|-)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\.|\s|/|-)', '', smart_text(value)) | ||||
|         m = phone_digits_re.search(value) | ||||
|         if m: | ||||
|             return '%s %s %s %s' % (value[0:3], value[3:6], value[6:8], value[8:10]) | ||||
|   | ||||
| @@ -8,7 +8,7 @@ from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import RegexField, Select | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
|  | ||||
| from .cl_regions import REGION_CHOICES | ||||
|  | ||||
| @@ -75,7 +75,7 @@ class CLRutField(RegexField): | ||||
|         Turns the RUT into one normalized format. Returns a (rut, verifier) | ||||
|         tuple. | ||||
|         """ | ||||
|         rut = smart_unicode(rut).replace(' ', '').replace('.', '').replace('-', '') | ||||
|         rut = smart_text(rut).replace(' ', '').replace('.', '').replace('-', '') | ||||
|         return rut[:-1], rut[-1].upper() | ||||
|  | ||||
|     def _format(self, code, verifier=None): | ||||
|   | ||||
| @@ -9,7 +9,7 @@ from django.contrib.localflavor.fr.fr_department import DEPARTMENT_CHOICES | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import CharField, RegexField, Select | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -43,7 +43,7 @@ class FRPhoneNumberField(CharField): | ||||
|         super(FRPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = re.sub('(\.|\s)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\.|\s)', '', smart_text(value)) | ||||
|         m = phone_digits_re.search(value) | ||||
|         if m: | ||||
|             return '%s %s %s %s %s' % (value[0:2], value[2:4], value[4:6], value[6:8], value[8:10]) | ||||
|   | ||||
| @@ -8,7 +8,7 @@ import re | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import CharField | ||||
| from django.forms import ValidationError | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -53,7 +53,7 @@ class HKPhoneNumberField(CharField): | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|  | ||||
|         value = re.sub('(\(|\)|\s+|\+)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\(|\)|\s+|\+)', '', smart_text(value)) | ||||
|         m = hk_phone_digits_re.search(value) | ||||
|         if not m: | ||||
|             raise ValidationError(self.error_messages['invalid']) | ||||
|   | ||||
| @@ -12,7 +12,7 @@ from django.contrib.localflavor.hr.hr_choices import ( | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, Select, RegexField | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -159,7 +159,7 @@ class HRLicensePlateField(Field): | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|  | ||||
|         value = re.sub(r'[\s\-]+', '', smart_unicode(value.strip())).upper() | ||||
|         value = re.sub(r'[\s\-]+', '', smart_text(value.strip())).upper() | ||||
|  | ||||
|         matches = plate_re.search(value) | ||||
|         if matches is None: | ||||
| @@ -225,7 +225,7 @@ class HRPhoneNumberField(Field): | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|  | ||||
|         value = re.sub(r'[\-\s\(\)]', '', smart_unicode(value)) | ||||
|         value = re.sub(r'[\-\s\(\)]', '', smart_text(value)) | ||||
|  | ||||
|         matches = phone_re.search(value) | ||||
|         if matches is None: | ||||
|   | ||||
| @@ -11,7 +11,7 @@ from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, Select | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
|  | ||||
|  | ||||
| postcode_re = re.compile(r'^[1-9]\d{4}$') | ||||
| @@ -77,10 +77,10 @@ class IDPhoneNumberField(Field): | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|  | ||||
|         phone_number = re.sub(r'[\-\s\(\)]', '', smart_unicode(value)) | ||||
|         phone_number = re.sub(r'[\-\s\(\)]', '', smart_text(value)) | ||||
|  | ||||
|         if phone_re.search(phone_number): | ||||
|             return smart_unicode(value) | ||||
|             return smart_text(value) | ||||
|  | ||||
|         raise ValidationError(self.error_messages['invalid']) | ||||
|  | ||||
| @@ -120,7 +120,7 @@ class IDLicensePlateField(Field): | ||||
|             return '' | ||||
|  | ||||
|         plate_number = re.sub(r'\s+', ' ', | ||||
|             smart_unicode(value.strip())).upper() | ||||
|             smart_text(value.strip())).upper() | ||||
|  | ||||
|         matches = plate_re.search(plate_number) | ||||
|         if matches is None: | ||||
| @@ -181,7 +181,7 @@ class IDNationalIdentityNumberField(Field): | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|  | ||||
|         value = re.sub(r'[\s.]', '', smart_unicode(value)) | ||||
|         value = re.sub(r'[\s.]', '', smart_text(value)) | ||||
|  | ||||
|         if not nik_re.search(value): | ||||
|             raise ValidationError(self.error_messages['invalid']) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ from django.contrib.localflavor.in_.in_states import STATES_NORMALIZED, STATE_CH | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, RegexField, CharField, Select | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -74,7 +74,7 @@ class INStateField(Field): | ||||
|             pass | ||||
|         else: | ||||
|             try: | ||||
|                 return smart_unicode(STATES_NORMALIZED[value.strip().lower()]) | ||||
|                 return smart_text(STATES_NORMALIZED[value.strip().lower()]) | ||||
|             except KeyError: | ||||
|                 pass | ||||
|         raise ValidationError(self.error_messages['invalid']) | ||||
| @@ -107,7 +107,7 @@ class INPhoneNumberField(CharField): | ||||
|         super(INPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = smart_unicode(value) | ||||
|         value = smart_text(value) | ||||
|         m = phone_digits_re.match(value) | ||||
|         if m: | ||||
|             return '%s' % (value) | ||||
|   | ||||
| @@ -9,7 +9,7 @@ from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import RegexField | ||||
| from django.forms.widgets import Select | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -58,7 +58,7 @@ class ISIdNumberField(RegexField): | ||||
|         Takes in the value in canonical form and returns it in the common | ||||
|         display format. | ||||
|         """ | ||||
|         return smart_unicode(value[:6]+'-'+value[6:]) | ||||
|         return smart_text(value[:6]+'-'+value[6:]) | ||||
|  | ||||
| class ISPhoneNumberField(RegexField): | ||||
|     """ | ||||
|   | ||||
| @@ -13,7 +13,7 @@ from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, RegexField, Select | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
|  | ||||
|  | ||||
| class ITZipCodeField(RegexField): | ||||
| @@ -85,4 +85,4 @@ class ITVatNumberField(Field): | ||||
|         check_digit = vat_number_check_digit(vat_number[0:10]) | ||||
|         if not vat_number[10] == check_digit: | ||||
|             raise ValidationError(self.error_messages['invalid']) | ||||
|         return smart_unicode(vat_number) | ||||
|         return smart_text(vat_number) | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
|  | ||||
| def ssn_check_digit(value): | ||||
|     "Calculate Italian social security number check digit." | ||||
| @@ -34,11 +34,11 @@ def ssn_check_digit(value): | ||||
|  | ||||
| def vat_number_check_digit(vat_number): | ||||
|     "Calculate Italian VAT number check digit." | ||||
|     normalized_vat_number = smart_unicode(vat_number).zfill(10) | ||||
|     normalized_vat_number = smart_text(vat_number).zfill(10) | ||||
|     total = 0 | ||||
|     for i in range(0, 10, 2): | ||||
|         total += int(normalized_vat_number[i]) | ||||
|     for i in range(1, 11, 2): | ||||
|         quotient , remainder = divmod(int(normalized_vat_number[i]) * 2, 10) | ||||
|         total += quotient + remainder | ||||
|     return smart_unicode((10 - total % 10) % 10) | ||||
|     return smart_text((10 - total % 10) % 10) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ from django.contrib.localflavor.nl.nl_provinces import PROVINCE_CHOICES | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, Select | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -61,7 +61,7 @@ class NLPhoneNumberField(Field): | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|  | ||||
|         phone_nr = re.sub('[\-\s\(\)]', '', smart_unicode(value)) | ||||
|         phone_nr = re.sub('[\-\s\(\)]', '', smart_text(value)) | ||||
|  | ||||
|         if len(phone_nr) == 10 and numeric_re.search(phone_nr): | ||||
|             return value | ||||
|   | ||||
| @@ -8,7 +8,7 @@ import re | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, RegexField | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
| phone_digits_re = re.compile(r'^(\d{9}|(00|\+)\d*)$') | ||||
| @@ -29,7 +29,7 @@ class PTZipCodeField(RegexField): | ||||
|            return '%s-%s' % (cleaned[:4],cleaned[4:]) | ||||
|         else: | ||||
|            return cleaned | ||||
|          | ||||
|  | ||||
| class PTPhoneNumberField(Field): | ||||
|     """ | ||||
|     Validate local Portuguese phone number (including international ones) | ||||
| @@ -43,7 +43,7 @@ class PTPhoneNumberField(Field): | ||||
|         super(PTPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = re.sub('(\.|\s)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\.|\s)', '', smart_text(value)) | ||||
|         m = phone_digits_re.search(value) | ||||
|         if m: | ||||
|             return '%s' % value | ||||
|   | ||||
| @@ -41,7 +41,7 @@ class SIEMSOField(CharField): | ||||
|         # Validate EMSO | ||||
|         s = 0 | ||||
|         int_values = [int(i) for i in value] | ||||
|         for a, b in zip(int_values, range(7, 1, -1) * 2): | ||||
|         for a, b in zip(int_values, list(range(7, 1, -1)) * 2): | ||||
|             s += a * b | ||||
|         chk = s % 11 | ||||
|         if chk == 0: | ||||
|   | ||||
| @@ -10,7 +10,7 @@ from django.contrib.localflavor.tr.tr_provinces import PROVINCE_CHOICES | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, RegexField, Select, CharField | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -46,7 +46,7 @@ class TRPhoneNumberField(CharField): | ||||
|         super(TRPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = re.sub('(\(|\)|\s+)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\(|\)|\s+)', '', smart_text(value)) | ||||
|         m = phone_digits_re.search(value) | ||||
|         if m: | ||||
|             return '%s%s' % (m.group(2), m.group(4)) | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import re | ||||
| from django.core.validators import EMPTY_VALUES | ||||
| from django.forms import ValidationError | ||||
| from django.forms.fields import Field, RegexField, Select, CharField | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -34,7 +34,7 @@ class USPhoneNumberField(CharField): | ||||
|         super(USPhoneNumberField, self).clean(value) | ||||
|         if value in EMPTY_VALUES: | ||||
|             return '' | ||||
|         value = re.sub('(\(|\)|\s+)', '', smart_unicode(value)) | ||||
|         value = re.sub('(\(|\)|\s+)', '', smart_text(value)) | ||||
|         m = phone_digits_re.search(value) | ||||
|         if m: | ||||
|             return '%s-%s-%s' % (m.group(1), m.group(2), m.group(3)) | ||||
|   | ||||
| @@ -13,7 +13,7 @@ markup syntaxes to HTML; currently there is support for: | ||||
|  | ||||
| from django import template | ||||
| from django.conf import settings | ||||
| from django.utils.encoding import smart_str, force_unicode | ||||
| from django.utils.encoding import smart_bytes, force_text | ||||
| from django.utils.safestring import mark_safe | ||||
|  | ||||
| register = template.Library() | ||||
| @@ -25,9 +25,9 @@ def textile(value): | ||||
|     except ImportError: | ||||
|         if settings.DEBUG: | ||||
|             raise template.TemplateSyntaxError("Error in 'textile' filter: The Python textile library isn't installed.") | ||||
|         return force_unicode(value) | ||||
|         return force_text(value) | ||||
|     else: | ||||
|         return mark_safe(force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8'))) | ||||
|         return mark_safe(force_text(textile.textile(smart_bytes(value), encoding='utf-8', output='utf-8'))) | ||||
|  | ||||
| @register.filter(is_safe=True) | ||||
| def markdown(value, arg=''): | ||||
| @@ -52,23 +52,23 @@ def markdown(value, arg=''): | ||||
|     except ImportError: | ||||
|         if settings.DEBUG: | ||||
|             raise template.TemplateSyntaxError("Error in 'markdown' filter: The Python markdown library isn't installed.") | ||||
|         return force_unicode(value) | ||||
|         return force_text(value) | ||||
|     else: | ||||
|         markdown_vers = getattr(markdown, "version_info", 0) | ||||
|         if markdown_vers < (2, 1): | ||||
|             if settings.DEBUG: | ||||
|                 raise template.TemplateSyntaxError( | ||||
|                     "Error in 'markdown' filter: Django does not support versions of the Python markdown library < 2.1.") | ||||
|             return force_unicode(value) | ||||
|             return force_text(value) | ||||
|         else: | ||||
|             extensions = [e for e in arg.split(",") if e] | ||||
|             if extensions and extensions[0] == "safe": | ||||
|                 extensions = extensions[1:] | ||||
|                 return mark_safe(markdown.markdown( | ||||
|                     force_unicode(value), extensions, safe_mode=True, enable_attributes=False)) | ||||
|                     force_text(value), extensions, safe_mode=True, enable_attributes=False)) | ||||
|             else: | ||||
|                 return mark_safe(markdown.markdown( | ||||
|                     force_unicode(value), extensions, safe_mode=False)) | ||||
|                     force_text(value), extensions, safe_mode=False)) | ||||
|  | ||||
| @register.filter(is_safe=True) | ||||
| def restructuredtext(value): | ||||
| @@ -77,8 +77,8 @@ def restructuredtext(value): | ||||
|     except ImportError: | ||||
|         if settings.DEBUG: | ||||
|             raise template.TemplateSyntaxError("Error in 'restructuredtext' filter: The Python docutils library isn't installed.") | ||||
|         return force_unicode(value) | ||||
|         return force_text(value) | ||||
|     else: | ||||
|         docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {}) | ||||
|         parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings) | ||||
|         return mark_safe(force_unicode(parts["fragment"])) | ||||
|         parts = publish_parts(source=smart_bytes(value), writer_name="html4css1", settings_overrides=docutils_settings) | ||||
|         return mark_safe(force_text(parts["fragment"])) | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.utils.encoding import force_unicode, StrAndUnicode | ||||
| from django.utils.encoding import force_text, StrAndUnicode | ||||
| from django.contrib.messages import constants, utils | ||||
|  | ||||
|  | ||||
| @@ -26,22 +26,22 @@ class Message(StrAndUnicode): | ||||
|         and ``extra_tags`` to unicode in case they are lazy translations. | ||||
|  | ||||
|         Known "safe" types (None, int, etc.) are not converted (see Django's | ||||
|         ``force_unicode`` implementation for details). | ||||
|         ``force_text`` implementation for details). | ||||
|         """ | ||||
|         self.message = force_unicode(self.message, strings_only=True) | ||||
|         self.extra_tags = force_unicode(self.extra_tags, strings_only=True) | ||||
|         self.message = force_text(self.message, strings_only=True) | ||||
|         self.extra_tags = force_text(self.extra_tags, strings_only=True) | ||||
|  | ||||
|     def __eq__(self, other): | ||||
|         return isinstance(other, Message) and self.level == other.level and \ | ||||
|                                               self.message == other.message | ||||
|  | ||||
|     def __unicode__(self): | ||||
|         return force_unicode(self.message) | ||||
|         return force_text(self.message) | ||||
|  | ||||
|     def _get_tags(self): | ||||
|         label_tag = force_unicode(LEVEL_TAGS.get(self.level, ''), | ||||
|         label_tag = force_text(LEVEL_TAGS.get(self.level, ''), | ||||
|                                   strings_only=True) | ||||
|         extra_tags = force_unicode(self.extra_tags, strings_only=True) | ||||
|         extra_tags = force_text(self.extra_tags, strings_only=True) | ||||
|         if extra_tags and label_tag: | ||||
|             return ' '.join([extra_tags, label_tag]) | ||||
|         elif extra_tags: | ||||
|   | ||||
| @@ -4,6 +4,7 @@ from django.conf import settings | ||||
| from django.contrib.messages.storage.base import BaseStorage, Message | ||||
| from django.http import SimpleCookie | ||||
| from django.utils.crypto import salted_hmac, constant_time_compare | ||||
| from django.utils import six | ||||
|  | ||||
|  | ||||
| class MessageEncoder(json.JSONEncoder): | ||||
| @@ -33,7 +34,7 @@ class MessageDecoder(json.JSONDecoder): | ||||
|             return [self.process_messages(item) for item in obj] | ||||
|         if isinstance(obj, dict): | ||||
|             return dict([(key, self.process_messages(value)) | ||||
|                          for key, value in obj.iteritems()]) | ||||
|                          for key, value in six.iteritems(obj)]) | ||||
|         return obj | ||||
|  | ||||
|     def decode(self, s, **kwargs): | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| from django.contrib.sessions.backends.base import SessionBase, CreateError | ||||
| from django.core.exceptions import SuspiciousOperation | ||||
| from django.db import IntegrityError, transaction, router | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils import timezone | ||||
|  | ||||
|  | ||||
| @@ -18,7 +18,7 @@ class SessionStore(SessionBase): | ||||
|                 session_key = self.session_key, | ||||
|                 expire_date__gt=timezone.now() | ||||
|             ) | ||||
|             return self.decode(force_unicode(s.session_data)) | ||||
|             return self.decode(force_text(s.session_data)) | ||||
|         except (Session.DoesNotExist, SuspiciousOperation): | ||||
|             self.create() | ||||
|             return {} | ||||
|   | ||||
| @@ -16,6 +16,7 @@ from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation | ||||
| from django.http import HttpResponse | ||||
| from django.test import TestCase, RequestFactory | ||||
| from django.test.utils import override_settings | ||||
| from django.utils import six | ||||
| from django.utils import timezone | ||||
| from django.utils import unittest | ||||
|  | ||||
| @@ -86,16 +87,16 @@ class SessionTestsMixin(object): | ||||
|         self.assertFalse(self.session.modified) | ||||
|  | ||||
|     def test_values(self): | ||||
|         self.assertEqual(self.session.values(), []) | ||||
|         self.assertEqual(list(self.session.values()), []) | ||||
|         self.assertTrue(self.session.accessed) | ||||
|         self.session['some key'] = 1 | ||||
|         self.assertEqual(self.session.values(), [1]) | ||||
|         self.assertEqual(list(self.session.values()), [1]) | ||||
|  | ||||
|     def test_iterkeys(self): | ||||
|         self.session['x'] = 1 | ||||
|         self.session.modified = False | ||||
|         self.session.accessed = False | ||||
|         i = self.session.iterkeys() | ||||
|         i = six.iterkeys(self.session) | ||||
|         self.assertTrue(hasattr(i, '__iter__')) | ||||
|         self.assertTrue(self.session.accessed) | ||||
|         self.assertFalse(self.session.modified) | ||||
| @@ -105,7 +106,7 @@ class SessionTestsMixin(object): | ||||
|         self.session['x'] = 1 | ||||
|         self.session.modified = False | ||||
|         self.session.accessed = False | ||||
|         i = self.session.itervalues() | ||||
|         i = six.itervalues(self.session) | ||||
|         self.assertTrue(hasattr(i, '__iter__')) | ||||
|         self.assertTrue(self.session.accessed) | ||||
|         self.assertFalse(self.session.modified) | ||||
| @@ -115,7 +116,7 @@ class SessionTestsMixin(object): | ||||
|         self.session['x'] = 1 | ||||
|         self.session.modified = False | ||||
|         self.session.accessed = False | ||||
|         i = self.session.iteritems() | ||||
|         i = six.iteritems(self.session) | ||||
|         self.assertTrue(hasattr(i, '__iter__')) | ||||
|         self.assertTrue(self.session.accessed) | ||||
|         self.assertFalse(self.session.modified) | ||||
| @@ -125,9 +126,9 @@ class SessionTestsMixin(object): | ||||
|         self.session['x'] = 1 | ||||
|         self.session.modified = False | ||||
|         self.session.accessed = False | ||||
|         self.assertEqual(self.session.items(), [('x', 1)]) | ||||
|         self.assertEqual(list(self.session.items()), [('x', 1)]) | ||||
|         self.session.clear() | ||||
|         self.assertEqual(self.session.items(), []) | ||||
|         self.assertEqual(list(self.session.items()), []) | ||||
|         self.assertTrue(self.session.accessed) | ||||
|         self.assertTrue(self.session.modified) | ||||
|  | ||||
| @@ -154,10 +155,10 @@ class SessionTestsMixin(object): | ||||
|         self.session['a'], self.session['b'] = 'c', 'd' | ||||
|         self.session.save() | ||||
|         prev_key = self.session.session_key | ||||
|         prev_data = self.session.items() | ||||
|         prev_data = list(self.session.items()) | ||||
|         self.session.cycle_key() | ||||
|         self.assertNotEqual(self.session.session_key, prev_key) | ||||
|         self.assertEqual(self.session.items(), prev_data) | ||||
|         self.assertEqual(list(self.session.items()), prev_data) | ||||
|  | ||||
|     def test_invalid_key(self): | ||||
|         # Submitting an invalid session key (either by guessing, or if the db has | ||||
|   | ||||
| @@ -3,6 +3,7 @@ from django.core import urlresolvers | ||||
| from django.core.paginator import EmptyPage, PageNotAnInteger | ||||
| from django.http import Http404 | ||||
| from django.template.response import TemplateResponse | ||||
| from django.utils import six | ||||
|  | ||||
| def index(request, sitemaps, | ||||
|           template_name='sitemap_index.xml', mimetype='application/xml', | ||||
| @@ -35,7 +36,7 @@ def sitemap(request, sitemaps, section=None, | ||||
|             raise Http404("No sitemap available for section: %r" % section) | ||||
|         maps = [sitemaps[section]] | ||||
|     else: | ||||
|         maps = sitemaps.values() | ||||
|         maps = list(six.itervalues(sitemaps)) | ||||
|     page = request.GET.get("p", 1) | ||||
|  | ||||
|     urls = [] | ||||
|   | ||||
| @@ -6,6 +6,7 @@ from django.utils.datastructures import SortedDict | ||||
| from django.utils.functional import empty, memoize, LazyObject | ||||
| from django.utils.importlib import import_module | ||||
| from django.utils._os import safe_join | ||||
| from django.utils import six | ||||
|  | ||||
| from django.contrib.staticfiles import utils | ||||
| from django.contrib.staticfiles.storage import AppStaticStorage | ||||
| @@ -132,7 +133,7 @@ class AppDirectoriesFinder(BaseFinder): | ||||
|         """ | ||||
|         List all files in all app storages. | ||||
|         """ | ||||
|         for storage in self.storages.itervalues(): | ||||
|         for storage in six.itervalues(self.storages): | ||||
|             if storage.exists(''):  # check if storage location exists | ||||
|                 for path in utils.get_files(storage, ignore_patterns): | ||||
|                     yield path, storage | ||||
|   | ||||
| @@ -6,8 +6,9 @@ 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_unicode | ||||
| 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 | ||||
|  | ||||
| @@ -148,7 +149,7 @@ class Command(NoArgsCommand): | ||||
|             clear_display = 'This will overwrite existing files!' | ||||
|  | ||||
|         if self.interactive: | ||||
|             confirm = raw_input(""" | ||||
|             confirm = input(""" | ||||
| You have requested to collect static files at the destination | ||||
| location as specified in your settings%s | ||||
|  | ||||
| @@ -198,9 +199,9 @@ Type 'yes' to continue, or 'no' to cancel: """ | ||||
|             fpath = os.path.join(path, f) | ||||
|             if self.dry_run: | ||||
|                 self.log("Pretending to delete '%s'" % | ||||
|                          smart_unicode(fpath), level=1) | ||||
|                          smart_text(fpath), level=1) | ||||
|             else: | ||||
|                 self.log("Deleting '%s'" % smart_unicode(fpath), level=1) | ||||
|                 self.log("Deleting '%s'" % smart_text(fpath), level=1) | ||||
|                 self.storage.delete(fpath) | ||||
|         for d in dirs: | ||||
|             self.clear_dir(os.path.join(path, d)) | ||||
|   | ||||
| @@ -3,7 +3,7 @@ from __future__ import unicode_literals | ||||
| import os | ||||
| from optparse import make_option | ||||
| from django.core.management.base import LabelCommand | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
|  | ||||
| from django.contrib.staticfiles import finders | ||||
|  | ||||
| @@ -19,12 +19,12 @@ class Command(LabelCommand): | ||||
|     def handle_label(self, path, **options): | ||||
|         verbosity = int(options.get('verbosity', 1)) | ||||
|         result = finders.find(path, all=options['all']) | ||||
|         path = smart_unicode(path) | ||||
|         path = smart_text(path) | ||||
|         if result: | ||||
|             if not isinstance(result, (list, tuple)): | ||||
|                 result = [result] | ||||
|             output = '\n  '.join( | ||||
|                 (smart_unicode(os.path.realpath(path)) for path in result)) | ||||
|                 (smart_text(os.path.realpath(path)) for path in result)) | ||||
|             self.stdout.write("Found '%s' here:\n  %s" % (path, output)) | ||||
|         else: | ||||
|             if verbosity >= 1: | ||||
|   | ||||
| @@ -16,7 +16,7 @@ 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_unicode, smart_str | ||||
| from django.utils.encoding import force_text, smart_bytes | ||||
| from django.utils.functional import LazyObject | ||||
| from django.utils.importlib import import_module | ||||
|  | ||||
| @@ -112,7 +112,7 @@ class CachedFilesMixin(object): | ||||
|         return urlunsplit(unparsed_name) | ||||
|  | ||||
|     def cache_key(self, name): | ||||
|         return 'staticfiles:%s' % hashlib.md5(smart_str(name)).hexdigest() | ||||
|         return 'staticfiles:%s' % hashlib.md5(smart_bytes(name)).hexdigest() | ||||
|  | ||||
|     def url(self, name, force=False): | ||||
|         """ | ||||
| @@ -248,9 +248,9 @@ class CachedFilesMixin(object): | ||||
|                     if hashed_file_exists: | ||||
|                         self.delete(hashed_name) | ||||
|                     # then save the processed result | ||||
|                     content_file = ContentFile(smart_str(content)) | ||||
|                     content_file = ContentFile(smart_bytes(content)) | ||||
|                     saved_name = self._save(hashed_name, content_file) | ||||
|                     hashed_name = force_unicode(saved_name.replace('\\', '/')) | ||||
|                     hashed_name = force_text(saved_name.replace('\\', '/')) | ||||
|                     processed = True | ||||
|                 else: | ||||
|                     # or handle the case in which neither processing nor | ||||
| @@ -258,7 +258,7 @@ class CachedFilesMixin(object): | ||||
|                     if not hashed_file_exists: | ||||
|                         processed = True | ||||
|                         saved_name = self._save(hashed_name, original_file) | ||||
|                         hashed_name = force_unicode(saved_name.replace('\\', '/')) | ||||
|                         hashed_name = force_text(saved_name.replace('\\', '/')) | ||||
|  | ||||
|                 # and then set the cache accordingly | ||||
|                 hashed_paths[self.cache_key(name)] = hashed_name | ||||
|   | ||||
| @@ -6,7 +6,7 @@ from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist | ||||
| from django.http import HttpResponse, Http404 | ||||
| from django.template import loader, TemplateDoesNotExist, RequestContext | ||||
| from django.utils import feedgenerator, tzinfo | ||||
| from django.utils.encoding import force_unicode, iri_to_uri, smart_unicode | ||||
| from django.utils.encoding import force_text, iri_to_uri, smart_text | ||||
| from django.utils.html import escape | ||||
| from django.utils.timezone import is_naive | ||||
|  | ||||
| @@ -43,10 +43,10 @@ class Feed(object): | ||||
|  | ||||
|     def item_title(self, item): | ||||
|         # Titles should be double escaped by default (see #6533) | ||||
|         return escape(force_unicode(item)) | ||||
|         return escape(force_text(item)) | ||||
|  | ||||
|     def item_description(self, item): | ||||
|         return force_unicode(item) | ||||
|         return force_text(item) | ||||
|  | ||||
|     def item_link(self, item): | ||||
|         try: | ||||
| @@ -154,9 +154,9 @@ class Feed(object): | ||||
|             enc_url = self.__get_dynamic_attr('item_enclosure_url', item) | ||||
|             if enc_url: | ||||
|                 enc = feedgenerator.Enclosure( | ||||
|                     url = smart_unicode(enc_url), | ||||
|                     length = smart_unicode(self.__get_dynamic_attr('item_enclosure_length', item)), | ||||
|                     mime_type = smart_unicode(self.__get_dynamic_attr('item_enclosure_mime_type', item)) | ||||
|                     url = smart_text(enc_url), | ||||
|                     length = smart_text(self.__get_dynamic_attr('item_enclosure_length', item)), | ||||
|                     mime_type = smart_text(self.__get_dynamic_attr('item_enclosure_mime_type', item)) | ||||
|                 ) | ||||
|             author_name = self.__get_dynamic_attr('item_author_name', item) | ||||
|             if author_name is not None: | ||||
|   | ||||
							
								
								
									
										6
									
								
								django/core/cache/backends/base.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								django/core/cache/backends/base.py
									
									
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| import warnings | ||||
|  | ||||
| from django.core.exceptions import ImproperlyConfigured, DjangoRuntimeWarning | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.encoding import smart_bytes | ||||
| from django.utils.importlib import import_module | ||||
|  | ||||
| class InvalidCacheBackendError(ImproperlyConfigured): | ||||
| @@ -23,7 +23,7 @@ def default_key_func(key, key_prefix, version): | ||||
|     the `key_prefix'. KEY_FUNCTION can be used to specify an alternate | ||||
|     function with custom key making behavior. | ||||
|     """ | ||||
|     return ':'.join([key_prefix, str(version), smart_str(key)]) | ||||
|     return ':'.join([key_prefix, str(version), smart_bytes(key)]) | ||||
|  | ||||
| def get_key_func(key_func): | ||||
|     """ | ||||
| @@ -62,7 +62,7 @@ class BaseCache(object): | ||||
|         except (ValueError, TypeError): | ||||
|             self._cull_frequency = 3 | ||||
|  | ||||
|         self.key_prefix = smart_str(params.get('KEY_PREFIX', '')) | ||||
|         self.key_prefix = smart_bytes(params.get('KEY_PREFIX', '')) | ||||
|         self.version = params.get('VERSION', 1) | ||||
|         self.key_func = get_key_func(params.get('KEY_FUNCTION', None)) | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ RequestContext. | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.middleware.csrf import get_token | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.encoding import smart_bytes | ||||
| from django.utils.functional import lazy | ||||
|  | ||||
| def csrf(request): | ||||
| @@ -25,7 +25,7 @@ def csrf(request): | ||||
|             # instead of returning an empty dict. | ||||
|             return b'NOTPROVIDED' | ||||
|         else: | ||||
|             return smart_str(token) | ||||
|             return smart_bytes(token) | ||||
|     _get_val = lazy(_get_val, str) | ||||
|  | ||||
|     return {'csrf_token': _get_val() } | ||||
|   | ||||
| @@ -43,7 +43,7 @@ class ValidationError(Exception): | ||||
|     """An error while validating data.""" | ||||
|     def __init__(self, message, code=None, params=None): | ||||
|         import operator | ||||
|         from django.utils.encoding import force_unicode | ||||
|         from django.utils.encoding import force_text | ||||
|         """ | ||||
|         ValidationError can be passed any object that can be printed (usually | ||||
|         a string), a list of objects or a dictionary. | ||||
| @@ -54,11 +54,11 @@ class ValidationError(Exception): | ||||
|             message = reduce(operator.add, message.values()) | ||||
|  | ||||
|         if isinstance(message, list): | ||||
|             self.messages = [force_unicode(msg) for msg in message] | ||||
|             self.messages = [force_text(msg) for msg in message] | ||||
|         else: | ||||
|             self.code = code | ||||
|             self.params = params | ||||
|             message = force_unicode(message) | ||||
|             message = force_text(message) | ||||
|             self.messages = [message] | ||||
|  | ||||
|     def __str__(self): | ||||
|   | ||||
| @@ -3,7 +3,7 @@ from __future__ import unicode_literals | ||||
| import os | ||||
| from io import BytesIO | ||||
|  | ||||
| from django.utils.encoding import smart_str, smart_unicode | ||||
| from django.utils.encoding import smart_bytes, smart_text | ||||
| from django.core.files.utils import FileProxyMixin | ||||
|  | ||||
| class File(FileProxyMixin): | ||||
| @@ -18,16 +18,17 @@ class File(FileProxyMixin): | ||||
|             self.mode = file.mode | ||||
|  | ||||
|     def __str__(self): | ||||
|         return smart_str(self.name or '') | ||||
|         return smart_bytes(self.name or '') | ||||
|  | ||||
|     def __unicode__(self): | ||||
|         return smart_unicode(self.name or '') | ||||
|         return smart_text(self.name or '') | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return "<%s: %s>" % (self.__class__.__name__, self or "None") | ||||
|  | ||||
|     def __nonzero__(self): | ||||
|     def __bool__(self): | ||||
|         return bool(self.name) | ||||
|     __nonzero__ = __bool__ # Python 2 | ||||
|  | ||||
|     def __len__(self): | ||||
|         return self.size | ||||
| @@ -135,8 +136,9 @@ class ContentFile(File): | ||||
|     def __str__(self): | ||||
|         return 'Raw content' | ||||
|  | ||||
|     def __nonzero__(self): | ||||
|     def __bool__(self): | ||||
|         return True | ||||
|     __nonzero__ = __bool__ # Python 2 | ||||
|  | ||||
|     def open(self, mode=None): | ||||
|         self.seek(0) | ||||
|   | ||||
| @@ -47,13 +47,18 @@ def get_image_dimensions(file_or_path, close=False): | ||||
|         file = open(file_or_path, 'rb') | ||||
|         close = True | ||||
|     try: | ||||
|         # Most of the time PIL only needs a small chunk to parse the image and | ||||
|         # get the dimensions, but with some TIFF files PIL needs to parse the | ||||
|         # whole file. | ||||
|         chunk_size = 1024 | ||||
|         while 1: | ||||
|             data = file.read(1024) | ||||
|             data = file.read(chunk_size) | ||||
|             if not data: | ||||
|                 break | ||||
|             p.feed(data) | ||||
|             if p.image: | ||||
|                 return p.image.size | ||||
|             chunk_size = chunk_size*2 | ||||
|         return None | ||||
|     finally: | ||||
|         if close: | ||||
|   | ||||
| @@ -11,7 +11,7 @@ from django.conf import settings | ||||
| from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation | ||||
| from django.core.files import locks, File | ||||
| from django.core.files.move import file_move_safe | ||||
| from django.utils.encoding import force_unicode, filepath_to_uri | ||||
| from django.utils.encoding import force_text, filepath_to_uri | ||||
| from django.utils.functional import LazyObject | ||||
| from django.utils.importlib import import_module | ||||
| from django.utils.text import get_valid_filename | ||||
| @@ -48,7 +48,7 @@ class Storage(object): | ||||
|         name = self._save(name, content) | ||||
|  | ||||
|         # Store filenames with forward slashes, even on Windows | ||||
|         return force_unicode(name.replace('\\', '/')) | ||||
|         return force_text(name.replace('\\', '/')) | ||||
|  | ||||
|     # These methods are part of the public API, with default implementations. | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,7 @@ from io import BytesIO | ||||
| from django.conf import settings | ||||
| from django.core.files.base import File | ||||
| from django.core.files import temp as tempfile | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.encoding import smart_bytes | ||||
|  | ||||
| __all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile', | ||||
|            'SimpleUploadedFile') | ||||
| @@ -30,7 +30,7 @@ class UploadedFile(File): | ||||
|         self.charset = charset | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return smart_str("<%s: %s (%s)>" % ( | ||||
|         return smart_bytes("<%s: %s (%s)>" % ( | ||||
|             self.__class__.__name__, self.name, self.content_type)) | ||||
|  | ||||
|     def _get_name(self): | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import sys | ||||
|  | ||||
| from django import http | ||||
| from django.core import signals | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils.importlib import import_module | ||||
| from django.utils.log import getLogger | ||||
| from django.utils import six | ||||
| @@ -250,7 +250,7 @@ def get_script_name(environ): | ||||
|     """ | ||||
|     from django.conf import settings | ||||
|     if settings.FORCE_SCRIPT_NAME is not None: | ||||
|         return force_unicode(settings.FORCE_SCRIPT_NAME) | ||||
|         return force_text(settings.FORCE_SCRIPT_NAME) | ||||
|  | ||||
|     # If Apache's mod_rewrite had a whack at the URL, Apache set either | ||||
|     # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any | ||||
| @@ -261,5 +261,5 @@ def get_script_name(environ): | ||||
|     if not script_url: | ||||
|         script_url = environ.get('REDIRECT_URL', '') | ||||
|     if script_url: | ||||
|         return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))]) | ||||
|     return force_unicode(environ.get('SCRIPT_NAME', '')) | ||||
|         return force_text(script_url[:-len(environ.get('PATH_INFO', ''))]) | ||||
|     return force_text(environ.get('SCRIPT_NAME', '')) | ||||
|   | ||||
| @@ -9,7 +9,7 @@ from django.core import signals | ||||
| from django.core.handlers import base | ||||
| from django.core.urlresolvers import set_script_prefix | ||||
| from django.utils import datastructures | ||||
| from django.utils.encoding import force_unicode, smart_str, iri_to_uri | ||||
| from django.utils.encoding import force_text, smart_bytes, iri_to_uri | ||||
| from django.utils.log import getLogger | ||||
|  | ||||
| logger = getLogger('django.request') | ||||
| @@ -127,7 +127,7 @@ class LimitedStream(object): | ||||
| class WSGIRequest(http.HttpRequest): | ||||
|     def __init__(self, environ): | ||||
|         script_name = base.get_script_name(environ) | ||||
|         path_info = force_unicode(environ.get('PATH_INFO', '/')) | ||||
|         path_info = force_text(environ.get('PATH_INFO', '/')) | ||||
|         if not path_info or path_info == script_name: | ||||
|             # Sometimes PATH_INFO exists, but is empty (e.g. accessing | ||||
|             # the SCRIPT_NAME URL without a trailing slash). We really need to | ||||
| @@ -245,6 +245,6 @@ class WSGIHandler(base.BaseHandler): | ||||
|         status = '%s %s' % (response.status_code, status_text) | ||||
|         response_headers = [(str(k), str(v)) for k, v in response.items()] | ||||
|         for c in response.cookies.values(): | ||||
|             response_headers.append((b'Set-Cookie', str(c.output(header='')))) | ||||
|         start_response(smart_str(status), response_headers) | ||||
|             response_headers.append((str('Set-Cookie'), str(c.output(header='')))) | ||||
|         start_response(smart_bytes(status), response_headers) | ||||
|         return response | ||||
|   | ||||
| @@ -11,11 +11,10 @@ from email.mime.multipart import MIMEMultipart | ||||
| from email.mime.base import MIMEBase | ||||
| from email.header import Header | ||||
| from email.utils import formatdate, getaddresses, formataddr, parseaddr | ||||
| from io import BytesIO | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.core.mail.utils import DNS_NAME | ||||
| from django.utils.encoding import smart_str, force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from django.utils import six | ||||
|  | ||||
|  | ||||
| @@ -79,38 +78,38 @@ ADDRESS_HEADERS = set([ | ||||
| def forbid_multi_line_headers(name, val, encoding): | ||||
|     """Forbids multi-line headers, to prevent header injection.""" | ||||
|     encoding = encoding or settings.DEFAULT_CHARSET | ||||
|     val = force_unicode(val) | ||||
|     val = force_text(val) | ||||
|     if '\n' in val or '\r' in val: | ||||
|         raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name)) | ||||
|     try: | ||||
|         val = val.encode('ascii') | ||||
|         val.encode('ascii') | ||||
|     except UnicodeEncodeError: | ||||
|         if name.lower() in ADDRESS_HEADERS: | ||||
|             val = ', '.join(sanitize_address(addr, encoding) | ||||
|                 for addr in getaddresses((val,))) | ||||
|         else: | ||||
|             val = str(Header(val, encoding)) | ||||
|             val = Header(val, encoding).encode() | ||||
|     else: | ||||
|         if name.lower() == 'subject': | ||||
|             val = Header(val) | ||||
|     return smart_str(name), val | ||||
|             val = Header(val).encode() | ||||
|     return str(name), val | ||||
|  | ||||
|  | ||||
| def sanitize_address(addr, encoding): | ||||
|     if isinstance(addr, six.string_types): | ||||
|         addr = parseaddr(force_unicode(addr)) | ||||
|         addr = parseaddr(force_text(addr)) | ||||
|     nm, addr = addr | ||||
|     nm = str(Header(nm, encoding)) | ||||
|     nm = Header(nm, encoding).encode() | ||||
|     try: | ||||
|         addr = addr.encode('ascii') | ||||
|         addr.encode('ascii') | ||||
|     except UnicodeEncodeError:  # IDN | ||||
|         if '@' in addr: | ||||
|             localpart, domain = addr.split('@', 1) | ||||
|             localpart = str(Header(localpart, encoding)) | ||||
|             domain = domain.encode('idna') | ||||
|             domain = domain.encode('idna').decode('ascii') | ||||
|             addr = '@'.join([localpart, domain]) | ||||
|         else: | ||||
|             addr = str(Header(addr, encoding)) | ||||
|             addr = Header(addr, encoding).encode() | ||||
|     return formataddr((nm, addr)) | ||||
|  | ||||
|  | ||||
| @@ -132,7 +131,7 @@ class SafeMIMEText(MIMEText): | ||||
|         This overrides the default as_string() implementation to not mangle | ||||
|         lines that begin with 'From '. See bug #13433 for details. | ||||
|         """ | ||||
|         fp = BytesIO() | ||||
|         fp = six.StringIO() | ||||
|         g = Generator(fp, mangle_from_ = False) | ||||
|         g.flatten(self, unixfrom=unixfrom) | ||||
|         return fp.getvalue() | ||||
| @@ -156,7 +155,7 @@ class SafeMIMEMultipart(MIMEMultipart): | ||||
|         This overrides the default as_string() implementation to not mangle | ||||
|         lines that begin with 'From '. See bug #13433 for details. | ||||
|         """ | ||||
|         fp = BytesIO() | ||||
|         fp = six.StringIO() | ||||
|         g = Generator(fp, mangle_from_ = False) | ||||
|         g.flatten(self, unixfrom=unixfrom) | ||||
|         return fp.getvalue() | ||||
| @@ -210,8 +209,7 @@ class EmailMessage(object): | ||||
|  | ||||
|     def message(self): | ||||
|         encoding = self.encoding or settings.DEFAULT_CHARSET | ||||
|         msg = SafeMIMEText(smart_str(self.body, encoding), | ||||
|                            self.content_subtype, encoding) | ||||
|         msg = SafeMIMEText(self.body, self.content_subtype, encoding) | ||||
|         msg = self._create_message(msg) | ||||
|         msg['Subject'] = self.subject | ||||
|         msg['From'] = self.extra_headers.get('From', self.from_email) | ||||
| @@ -293,7 +291,7 @@ class EmailMessage(object): | ||||
|         basetype, subtype = mimetype.split('/', 1) | ||||
|         if basetype == 'text': | ||||
|             encoding = self.encoding or settings.DEFAULT_CHARSET | ||||
|             attachment = SafeMIMEText(smart_str(content, encoding), subtype, encoding) | ||||
|             attachment = SafeMIMEText(content, subtype, encoding) | ||||
|         else: | ||||
|             # Encode non-text attachments with base64. | ||||
|             attachment = MIMEBase(basetype, subtype) | ||||
| @@ -313,9 +311,11 @@ class EmailMessage(object): | ||||
|         attachment = self._create_mime_attachment(content, mimetype) | ||||
|         if filename: | ||||
|             try: | ||||
|                 filename = filename.encode('ascii') | ||||
|                 filename.encode('ascii') | ||||
|             except UnicodeEncodeError: | ||||
|                 filename = ('utf-8', '', filename.encode('utf-8')) | ||||
|                 if not six.PY3: | ||||
|                     filename = filename.encode('utf-8') | ||||
|                 filename = ('utf-8', '', filename) | ||||
|             attachment.add_header('Content-Disposition', 'attachment', | ||||
|                                   filename=filename) | ||||
|         return attachment | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import warnings | ||||
| from django.core.management.base import BaseCommand, CommandError, handle_default_options | ||||
| from django.core.management.color import color_style | ||||
| from django.utils.importlib import import_module | ||||
| from django.utils import six | ||||
|  | ||||
| # For backwards compatibility: get_version() used to be in this module. | ||||
| from django import get_version | ||||
| @@ -228,7 +229,7 @@ class ManagementUtility(object): | ||||
|                 "Available subcommands:", | ||||
|             ] | ||||
|             commands_dict = collections.defaultdict(lambda: []) | ||||
|             for name, app in get_commands().iteritems(): | ||||
|             for name, app in six.iteritems(get_commands()): | ||||
|                 if app == 'django.core': | ||||
|                     app = 'django' | ||||
|                 else: | ||||
| @@ -294,7 +295,7 @@ class ManagementUtility(object): | ||||
|         except IndexError: | ||||
|             curr = '' | ||||
|  | ||||
|         subcommands = get_commands().keys() + ['help'] | ||||
|         subcommands = list(get_commands()) + ['help'] | ||||
|         options = [('--help', None)] | ||||
|  | ||||
|         # subcommand | ||||
|   | ||||
| @@ -6,7 +6,6 @@ be executed through ``django-admin.py`` or ``manage.py``). | ||||
| import os | ||||
| import sys | ||||
|  | ||||
| from io import BytesIO | ||||
| from optparse import make_option, OptionParser | ||||
| import traceback | ||||
|  | ||||
| @@ -14,6 +13,7 @@ import django | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.core.management.color import color_style | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.six import StringIO | ||||
|  | ||||
|  | ||||
| class CommandError(Exception): | ||||
| @@ -273,7 +273,7 @@ class BaseCommand(object): | ||||
|  | ||||
|         """ | ||||
|         from django.core.management.validation import get_validation_errors | ||||
|         s = BytesIO() | ||||
|         s = StringIO() | ||||
|         num_errors = get_validation_errors(s, app) | ||||
|         if num_errors: | ||||
|             s.seek(0) | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import codecs | ||||
| import os | ||||
| import sys | ||||
| @@ -7,7 +9,7 @@ from django.core.management.base import BaseCommand, CommandError | ||||
| def has_bom(fn): | ||||
|     with open(fn, 'rb') as f: | ||||
|         sample = f.read(4) | ||||
|     return sample[:3] == '\xef\xbb\xbf' or \ | ||||
|     return sample[:3] == b'\xef\xbb\xbf' or \ | ||||
|             sample.startswith(codecs.BOM_UTF16_LE) or \ | ||||
|             sample.startswith(codecs.BOM_UTF16_BE) | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ from django.core.cache.backends.db import BaseDatabaseCache | ||||
| from django.core.management.base import LabelCommand, CommandError | ||||
| from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS | ||||
| from django.db.utils import DatabaseError | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
|  | ||||
|  | ||||
| class Command(LabelCommand): | ||||
| @@ -60,7 +60,7 @@ class Command(LabelCommand): | ||||
|             transaction.rollback_unless_managed(using=db) | ||||
|             raise CommandError( | ||||
|                 "Cache table '%s' could not be created.\nThe error was: %s." % | ||||
|                     (tablename, force_unicode(e))) | ||||
|                     (tablename, force_text(e))) | ||||
|         for statement in index_output: | ||||
|             curs.execute(statement) | ||||
|         transaction.commit_unless_managed(using=db) | ||||
|   | ||||
| @@ -22,9 +22,7 @@ class Command(NoArgsCommand): | ||||
|         default_settings = module_to_dict(global_settings) | ||||
|  | ||||
|         output = [] | ||||
|         keys = user_settings.keys() | ||||
|         keys.sort() | ||||
|         for key in keys: | ||||
|         for key in sorted(user_settings.keys()): | ||||
|             if key not in default_settings: | ||||
|                 output.append("%s = %s  ###" % (key, user_settings[key])) | ||||
|             elif user_settings[key] != default_settings[key]: | ||||
|   | ||||
| @@ -7,6 +7,7 @@ from django.core.management.base import NoArgsCommand, CommandError | ||||
| from django.core.management.color import no_style | ||||
| from django.core.management.sql import sql_flush, emit_post_sync_signal | ||||
| from django.utils.importlib import import_module | ||||
| from django.utils.six.moves import input | ||||
|  | ||||
|  | ||||
| class Command(NoArgsCommand): | ||||
| @@ -45,7 +46,7 @@ class Command(NoArgsCommand): | ||||
|         sql_list = sql_flush(self.style, connection, only_django=True, reset_sequences=reset_sequences) | ||||
|  | ||||
|         if interactive: | ||||
|             confirm = raw_input("""You have requested a flush of the database. | ||||
|             confirm = input("""You have requested a flush of the database. | ||||
| This will IRREVERSIBLY DESTROY all data currently in the %r database, | ||||
| and return each table to the state it was in after syncdb. | ||||
| Are you sure you want to do this? | ||||
|   | ||||
| @@ -14,7 +14,7 @@ from django.core.management.color import no_style | ||||
| from django.db import (connections, router, transaction, DEFAULT_DB_ALIAS, | ||||
|       IntegrityError, DatabaseError) | ||||
| from django.db.models import get_apps | ||||
| from django.utils.encoding import force_unicode | ||||
| from django.utils.encoding import force_text | ||||
| from itertools import product | ||||
|  | ||||
| try: | ||||
| @@ -189,7 +189,7 @@ class Command(BaseCommand): | ||||
|                                                         'app_label': obj.object._meta.app_label, | ||||
|                                                         'object_name': obj.object._meta.object_name, | ||||
|                                                         'pk': obj.object.pk, | ||||
|                                                         'error_msg': force_unicode(e) | ||||
|                                                         'error_msg': force_text(e) | ||||
|                                                     },) | ||||
|                                                 raise | ||||
|  | ||||
|   | ||||
| @@ -18,6 +18,7 @@ To add your own serializers, use the SERIALIZATION_MODULES setting:: | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.utils import importlib | ||||
| from django.utils import six | ||||
| from django.core.serializers.base import SerializerDoesNotExist | ||||
|  | ||||
| # Built-in serializers | ||||
| @@ -75,12 +76,12 @@ def get_serializer(format): | ||||
| def get_serializer_formats(): | ||||
|     if not _serializers: | ||||
|         _load_serializers() | ||||
|     return _serializers.keys() | ||||
|     return list(_serializers) | ||||
|  | ||||
| def get_public_serializer_formats(): | ||||
|     if not _serializers: | ||||
|         _load_serializers() | ||||
|     return [k for k, v in _serializers.iteritems() if not v.Serializer.internal_use_only] | ||||
|     return [k for k, v in six.iteritems(_serializers) if not v.Serializer.internal_use_only] | ||||
|  | ||||
| def get_deserializer(format): | ||||
|     if not _serializers: | ||||
|   | ||||
| @@ -5,7 +5,7 @@ Module for abstract serializer/unserializer base classes. | ||||
| from io import BytesIO | ||||
|  | ||||
| from django.db import models | ||||
| from django.utils.encoding import smart_unicode | ||||
| from django.utils.encoding import smart_text | ||||
| from django.utils import six | ||||
|  | ||||
| class SerializerDoesNotExist(KeyError): | ||||
| @@ -136,10 +136,12 @@ class Deserializer(object): | ||||
|     def __iter__(self): | ||||
|         return self | ||||
|  | ||||
|     def next(self): | ||||
|     def __next__(self): | ||||
|         """Iteration iterface -- return the next item in the stream""" | ||||
|         raise NotImplementedError | ||||
|  | ||||
|     next = __next__             # Python 2 compatibility | ||||
|  | ||||
| class DeserializedObject(object): | ||||
|     """ | ||||
|     A deserialized model. | ||||
|   | ||||
| @@ -12,7 +12,7 @@ import json | ||||
| from django.core.serializers.base import DeserializationError | ||||
| from django.core.serializers.python import Serializer as PythonSerializer | ||||
| from django.core.serializers.python import Deserializer as PythonDeserializer | ||||
| from django.utils.encoding import smart_str | ||||
| from django.utils.encoding import smart_bytes | ||||
| from django.utils import six | ||||
| from django.utils.timezone import is_aware | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,8 @@ from __future__ import unicode_literals | ||||
| from django.conf import settings | ||||
| from django.core.serializers import base | ||||
| from django.db import models, DEFAULT_DB_ALIAS | ||||
| from django.utils.encoding import smart_unicode, is_protected_type | ||||
| from django.utils.encoding import smart_text, is_protected_type | ||||
| from django.utils import six | ||||
|  | ||||
| class Serializer(base.Serializer): | ||||
|     """ | ||||
| @@ -33,8 +34,8 @@ class Serializer(base.Serializer): | ||||
|  | ||||
|     def get_dump_object(self, obj): | ||||
|         return { | ||||
|             "pk": smart_unicode(obj._get_pk_val(), strings_only=True), | ||||
|             "model": smart_unicode(obj._meta), | ||||
|             "pk": smart_text(obj._get_pk_val(), strings_only=True), | ||||
|             "model": smart_text(obj._meta), | ||||
|             "fields": self._current | ||||
|         } | ||||
|  | ||||
| @@ -64,7 +65,7 @@ class Serializer(base.Serializer): | ||||
|             if self.use_natural_keys and hasattr(field.rel.to, 'natural_key'): | ||||
|                 m2m_value = lambda value: value.natural_key() | ||||
|             else: | ||||
|                 m2m_value = lambda value: smart_unicode(value._get_pk_val(), strings_only=True) | ||||
|                 m2m_value = lambda value: smart_text(value._get_pk_val(), strings_only=True) | ||||
|             self._current[field.name] = [m2m_value(related) | ||||
|                                for related in getattr(obj, field.name).iterator()] | ||||
|  | ||||
| @@ -87,9 +88,9 @@ def Deserializer(object_list, **options): | ||||
|         m2m_data = {} | ||||
|  | ||||
|         # Handle each field | ||||
|         for (field_name, field_value) in d["fields"].iteritems(): | ||||
|         for (field_name, field_value) in six.iteritems(d["fields"]): | ||||
|             if isinstance(field_value, str): | ||||
|                 field_value = smart_unicode(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True) | ||||
|                 field_value = smart_text(field_value, options.get("encoding", settings.DEFAULT_CHARSET), strings_only=True) | ||||
|  | ||||
|             field = Model._meta.get_field(field_name) | ||||
|  | ||||
| @@ -97,19 +98,19 @@ def Deserializer(object_list, **options): | ||||
|             if field.rel and isinstance(field.rel, models.ManyToManyRel): | ||||
|                 if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): | ||||
|                     def m2m_convert(value): | ||||
|                         if hasattr(value, '__iter__'): | ||||
|                         if hasattr(value, '__iter__') and not isinstance(value, six.text_type): | ||||
|                             return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk | ||||
|                         else: | ||||
|                             return smart_unicode(field.rel.to._meta.pk.to_python(value)) | ||||
|                             return smart_text(field.rel.to._meta.pk.to_python(value)) | ||||
|                 else: | ||||
|                     m2m_convert = lambda v: smart_unicode(field.rel.to._meta.pk.to_python(v)) | ||||
|                     m2m_convert = lambda v: smart_text(field.rel.to._meta.pk.to_python(v)) | ||||
|                 m2m_data[field.name] = [m2m_convert(pk) for pk in field_value] | ||||
|  | ||||
|             # Handle FK fields | ||||
|             elif field.rel and isinstance(field.rel, models.ManyToOneRel): | ||||
|                 if field_value is not None: | ||||
|                     if hasattr(field.rel.to._default_manager, 'get_by_natural_key'): | ||||
|                         if hasattr(field_value, '__iter__'): | ||||
|                         if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type): | ||||
|                             obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value) | ||||
|                             value = getattr(obj, field.rel.field_name) | ||||
|                             # If this is a natural foreign key to an object that | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user