如果我有Django表单,例如:
class ContactForm(forms.Form): subject = forms.CharField(max_length=100) message = forms.CharField() sender = forms.EmailField()
我调用了这种形式的实例的as_table()方法,Django将按照上述指定的顺序渲染字段。
我的问题是Django如何知道类变量的定义顺序?
(例如,当我想从类的init方法中添加字段时,如何覆盖此顺序?)
我继续回答了自己的问题。这是供将来参考的答案:
在Django form.py中,使用该__new__方法将类变量最终self.fields按类中定义的顺序加载到其中,这确实有些不可思议。 self.fields是Django SortedDict实例(在中定义datastructures.py)。
Django form.py
__new__
self.fields
Django 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())))
[注意:这个答案现在已经完全过时了-请参阅下面的讨论以及更多最新答案]。
如果f是表单,则其字段是f.fields,这是django.utils.datastructures.SortedDict (它按添加顺序显示项目)。表单构造之后,f.fields具有keyOrder属性,该属性是一个列表,其中包含字段名称的显示顺序。你可以将其设置为正确的顺序(尽管你需要格外小心,以确保你不会遗漏任何物品或添加其他物品)。
f.fields
django.utils.datastructures.SortedDict
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