一尘不染

Django如何知道呈现表单字段的顺序?

django

如果我有Django表单,例如:

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    sender = forms.EmailField()

我调用了这种形式的实例的as_table()方法,Django将按照上述指定的顺序渲染字段。

我的问题是Django如何知道类变量的定义顺序?

(例如,当我想从类的init方法中添加字段时,如何覆盖此顺序?)


阅读 646

收藏
2020-03-27

共2个答案

一尘不染

我继续回答了自己的问题。这是供将来参考的答案:

Django form.py中,使用该__new__方法将类变量最终self.fields按类中定义的顺序加载到其中,这确实有些不可思议。 self.fieldsDjango SortedDict实例(在中定义datastructures.py)。

因此,要覆盖此内容,请在我的示例中说,你希望发送者优先,但需要在init方法中添加它,你可以这样做:

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    def __init__(self,*args,**kwargs):
        forms.Form.__init__(self,*args,**kwargs)
        #first argument, index is the position of the field you want it to come before
        self.fields.insert(0,'sender',forms.EmailField(initial=str(time.time())))
2020-03-27
一尘不染

[注意:这个答案现在已经完全过时了-请参阅下面的讨论以及更多最新答案]。

如果f是表单,则其字段是f.fields,这是django.utils.datastructures.SortedDict (它按添加顺序显示项目)。表单构造之后,f.fields具有keyOrder属性,该属性是一个列表,其中包含字段名称的显示顺序。你可以将其设置为正确的顺序(尽管你需要格外小心,以确保你不会遗漏任何物品或添加其他物品)。

这是我在当前项目中刚刚创建的一个示例:

class PrivEdit(ModelForm):
    def __init__(self, *args, **kw):
        super(ModelForm, self).__init__(*args, **kw)
        self.fields.keyOrder = [
            'super_user',
            'all_districts',
            'multi_district',
            'all_schools',
            'manage_users',
            'direct_login',
            'student_detail',
            'license']
    class Meta:
        model = Privilege
2020-03-27