Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #10645 -- Added some robustness around some admin and modelform…

… params.

Fieldset dictionary names, search fields and unique_together attribute
names all have to be convertible to strings (that has always been true).
If somebody passes in a unicode object, Python barfs because Django uses
those values as keyword argument names and function calls require
parameter names to be str objects. We now convert thing to strs
automatically.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10510 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 3bd384aa62608ca2aebdf6d86ae1a75abb96f4bf 1 parent d2fc8ae
@malcolmt malcolmt authored
View
24 django/contrib/admin/helpers.py
@@ -17,7 +17,7 @@ class ActionForm(forms.Form):
class AdminForm(object):
def __init__(self, form, fieldsets, prepopulated_fields):
- self.form, self.fieldsets = form, fieldsets
+ self.form, self.fieldsets = form, normalize_fieldsets(fieldsets)
self.prepopulated_fields = [{
'field': form[field_name],
'dependencies': [form[f] for f in dependencies]
@@ -196,3 +196,25 @@ def __init__(self, form, 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())
+
+def normalize_fieldsets(fieldsets):
+ """
+ Make sure the keys in fieldset dictionaries are strings. Returns the
+ normalized data.
+ """
+ result = []
+ for name, options in fieldsets:
+ result.append((name, normalize_dictionary(options)))
+ return result
+
+def normalize_dictionary(data_dict):
+ """
+ Converts all the keys in "data_dict" to strings. The keys must be
+ convertible using str().
+ """
+ for key, value in data_dict.items():
+ if not isinstance(key, str):
+ del data_dict[key]
+ data_dict[str(key)] = value
+ return data_dict
+
View
2  django/contrib/admin/views/main.py
@@ -228,7 +228,7 @@ def construct_search(field_name):
if self.search_fields and self.query:
for bit in self.query.split():
- or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.search_fields]
+ or_queries = [models.Q(**{construct_search(str(field_name)): bit}) for field_name in self.search_fields]
other_qs = QuerySet(self.model)
other_qs.dup_select_related(qs)
other_qs = other_qs.filter(reduce(operator.or_, or_queries))
View
2  django/forms/models.py
@@ -276,7 +276,7 @@ def validate_unique(self):
# using it in a lookup.
if isinstance(self.fields[field_name], ModelChoiceField):
lookup_value = lookup_value.pk
- lookup_kwargs[field_name] = lookup_value
+ lookup_kwargs[str(field_name)] = lookup_value
qs = self.instance.__class__._default_manager.filter(**lookup_kwargs)
View
2  tests/regressiontests/admin_views/models.py
@@ -169,7 +169,7 @@ class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'gender', 'alive')
list_editable = ('gender', 'alive')
list_filter = ('gender',)
- search_fields = ('name',)
+ search_fields = (u'name',)
ordering = ["id"]
class Persona(models.Model):
View
2  tests/regressiontests/model_forms_regress/models.py
@@ -11,7 +11,7 @@ def __unicode__(self):
return u"%d, %d, %d" % (self.left, self.middle, self.right)
class Meta:
- unique_together = (('left', 'middle'), ('middle', 'right'))
+ unique_together = (('left', 'middle'), (u'middle', u'right'))
class FilePathModel(models.Model):
path = models.FilePathField(path=os.path.dirname(__file__), match=".*\.py$", blank=True)
Please sign in to comment.
Something went wrong with that request. Please try again.