From 3abf8e42b550445d94683e5d9c0f7b12557ddf1f Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Thu, 23 Nov 2006 17:40:33 +0000 Subject: [PATCH] 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 --- django/newforms/fields.py | 7 +++++++ django/newforms/forms.py | 14 +++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) 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):