Friday, July 27, 2012

ModelForms with custom non-model fields (trying to preserve field ordering)





class ProductAddForm(forms.ModelForm):
    """ Make a form with extra fields, to save as well to property table.
        Operator-specific Customization Params:


        1. URL field for MobSec only download page
        2. URL field for System Requirements (Both MobSec and IS products.)


        Caveats:
        Enforce saving to property table only if key is unique!
    """
    # Custom non-model fields: First thing, lang dropdown box first.
    lang = forms.ChoiceField()
    operator = ReadOnlyField()


    def __init__(self, *args, **kwargs):
        """ Smart way to take care of reordering fields with custom non-model fields,
            without having to explicitly state every field in Meta.fields.
            http://djangosnippets.org/snippets/759/


            Although it may be overkill here but sometimes we don't (want to) know all the other
            fields in the modelform beforehand and type them out in fields=(,) explicitly,
            OR we wanted to preserve the exact fields order in the existing ModelForm.


            desired_order : desired order of the new fields (go by key names)
            The key names are the names of the non-model fields that you defined in this ModelForm (look above.)
        """
        super(ProductAddForm, self).__init__(*args, **kwargs)
        desired_order = ('lang',)
        desired_list = []
        for key in desired_order:
            for k in self.fields.keys()[:]:
                if k==key:
                    val = self.fields.pop(k)
                    desired_list.append((key,val)) # desired_list.append({ key: val })


        print "1=", val
        print "2=", self.fields
        print "3=", desired_list


##        for item in desired_list[::-1]:
##            self.fields.insert(0, item) #REMINDER NOTE: DON'T USE .insert it is deprecated.


        self.fields = SortedDict(desired_list + self.fields.items()) # https://code.djangoproject.com/wiki/SortedDict
        print "4=", "done"


    class Meta:
        model = Product
##        widgets = {
##            'operator': ReadOnlyField(),
##        }











No comments:

Post a Comment