Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #3054 -- newforms Form now keeps track of field order

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4093 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 3abf8e42b550445d94683e5d9c0f7b12557ddf1f 1 parent 5836b14
@adrianholovaty adrianholovaty authored
Showing with 20 additions and 1 deletion.
  1. +7 −0 django/newforms/fields.py
  2. +13 −1 django/newforms/forms.py
View
7 django/newforms/fields.py
@@ -28,6 +28,9 @@
class Field(object):
widget = TextInput # Default widget to use when rendering this type of Field.
+ # Tracks each time a Field instance is created. Used to retain order.
+ creation_counter = 0
+
def __init__(self, required=True, widget=None):
self.required = required
widget = widget or self.widget
@@ -35,6 +38,10 @@ def __init__(self, required=True, widget=None):
widget = widget()
self.widget = widget
+ # Increase the creation counter, and save our local copy.
+ self.creation_counter = Field.creation_counter
+ Field.creation_counter += 1
+
def clean(self, value):
"""
Validates the given value and returns its "cleaned" value as an
View
14 django/newforms/forms.py
@@ -2,6 +2,7 @@
Form classes
"""
+from django.utils.datastructures import SortedDict
from fields import Field
from widgets import TextInput, Textarea
from util import ErrorDict, ErrorList, ValidationError
@@ -13,10 +14,21 @@ def pretty_name(name):
name = name[0].upper() + name[1:]
return name.replace('_', ' ')
+class SortedDictFromList(SortedDict):
+ "A dictionary that keeps its keys in the order in which they're inserted."
+ # This is different than django.utils.datastructures.SortedDict, because
+ # this takes a list/tuple as the argument to __init__().
+ def __init__(self, data=None):
+ if data is None: data = []
+ self.keyOrder = [d[0] for d in data]
+ dict.__init__(self, dict(data))
+
class DeclarativeFieldsMetaclass(type):
"Metaclass that converts Field attributes to a dictionary called 'fields'."
def __new__(cls, name, bases, attrs):
- attrs['fields'] = dict([(name, attrs.pop(name)) for name, obj in attrs.items() if isinstance(obj, Field)])
+ fields = [(name, attrs.pop(name)) for name, obj in attrs.items() if isinstance(obj, Field)]
+ fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
+ attrs['fields'] = SortedDictFromList(fields)
return type.__new__(cls, name, bases, attrs)
class Form(object):
Please sign in to comment.
Something went wrong with that request. Please try again.