summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Holovaty <adrian@holovaty.com>2006-11-23 17:40:33 +0000
committerAdrian Holovaty <adrian@holovaty.com>2006-11-23 17:40:33 +0000
commit3abf8e42b550445d94683e5d9c0f7b12557ddf1f (patch)
tree2d12261fb1c8e4a267efa3a009d8289d68077160
parent5836b140fabbf24c05dea3a8862e65b281ded3ad (diff)
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
-rw-r--r--django/newforms/fields.py7
-rw-r--r--django/newforms/forms.py14
2 files changed, 20 insertions, 1 deletions
diff --git a/django/newforms/fields.py b/django/newforms/fields.py
index 179555fc77..40fc18bd3e 100644
--- a/django/newforms/fields.py
+++ b/django/newforms/fields.py
@@ -28,6 +28,9 @@ except NameError:
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 @@ class Field(object):
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
diff --git a/django/newforms/forms.py b/django/newforms/forms.py
index 2730bfe4e4..b8264fb691 100644
--- a/django/newforms/forms.py
+++ b/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):