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

2024-06-03 03:33:24 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我有一份Django表格,比如:

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

我调用此表单实例的as_table()方法,Django将按照上面指定的顺序呈现字段。

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

(另外,我如何重写这个顺序,例如当我想从类的init方法中添加一个字段时?)


Tags: django方法formmessage顺序formslengthmax
3条回答

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

如果f是一个表单,那么它的字段是f.fields,这是一个django.utils.datastructures.SortedDict(它按添加的顺序显示项)。After form construction 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

我继续回答自己的问题。以下是供日后参考的答案:

在Django中,form.py使用__new__方法执行一些黑暗魔法,以类中定义的顺序将类变量最终加载到self.fieldsself.fields是一个Django SortedDict实例(在datastructures.py中定义)。

所以要重写这个,假设在我的示例中,您希望sender优先,但需要将其添加到init~/strong>方法中,您可以:

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())))

Django 1.9的新特性是Form.field_orderForm.order_fields()

# forms.Form example
class SignupForm(forms.Form):

    password = ...
    email = ...
    username = ...

    field_order = ['username', 'email', 'password']


# forms.ModelForm example
class UserAccount(forms.ModelForm):

    custom_field = models.CharField(max_length=254)

    def Meta:
        model = User
        fields = ('username', 'email')

    field_order = ['username', 'custom_field', 'password']

相关问题 更多 >