重新排序模型表单字段

Posted

技术标签:

【中文标题】重新排序模型表单字段【英文标题】:Reorder modelform fields 【发布时间】:2011-07-01 16:40:27 【问题描述】:

我需要对来自另一个基类的模型表单中的字段重新排序。找不到解决方案。下面 sn-p 中的“地址”始终显示在 html 模板的开头。如何使用渲染的模板将其进一步向下移动?提前致谢。

class Address:
   street= ...
   city= ...

class Customer(Address):
   name = ...
   ...

class CustomerForm(ModelForm):
   def __init__(...)
        super(CustomerForm, self).__init__(*args, **kw)
        self.fields.keyOrder=[
        'name',
        'Address',  #<-- I want "Address" appear after the name in my template
                    #<-- This obviously is not the right code.
   class Meta:
      model = Customer

-P

【问题讨论】:

【参考方案1】:

重新排序是相当乏味的:

# django's SortedDict stores ordering of its fields in this list-type attribute:
keyorder = self.fields.keyOrder

# Remove fields which we want to displace:
keyorder.remove('street')
keyorder.remove('city')

# Get position where we want them to put in:
i = keyorder.index('name') + 1

# Insert items back into the list:
keyorder[i:i] = ['city', 'street']

以正确的顺序再次列出所有字段可能更好:

class MyForm(ModelForm):
    class Meta:
       model=Customer
       fields=[..., 'name', 'street', 'city', ...]

【讨论】:

感谢 Skirmantas!我尝试了第二种方法,效果很好。我正在尝试类似'name'、'Address.street'....非常感谢您的时间。【参考方案2】:

当我们升级到 Django 1.7 时,Skyjur 对 .keyOrder 的使用停止工作(Django 现在改用 collections.OrderedDict)。结果,我不得不找到一种解决方法,这似乎对我有用:

from collections import OrderedDict
...
class MyForm(forms
    def __init__(self, *args, **kwargs):
        fields = OrderedDict()
        for key in ("my_preferred_first_field", "my_preferred_second_field"):
            fields[key] = self.fields.pop(key)
        for key, value in self.fields.items():
            fields[key] = value
        self.fields = fields

【讨论】:

【参考方案3】:
from django import forms

class CustomForm(forms.Form):
    ORDER = ('field1', 'field2', 'field3')
    def __init__(self, *args, **kwargs):
        super(CustomForm, self).__init__(*args, **kwargs)
        fields = OrderedDict()
        for key in self.ORDER:
            fields[key] = self.fields.pop(key)
        self.fields = fields

【讨论】:

欢迎来到 SO 并感谢您发布答案。请考虑为您的代码发布上下文。 使用这个的人记得导入from collections import OrderedDict【参考方案4】:

在 Django 1.9 中,他们向 Form 类添加了新参数 现在您可以通过定义 field_order 来更改顺序 例如在 userena 申请表中添加两个字段:

class SignupFormExtra(SignupForm):
    """
    A form to demonstrate how to add extra fields to the signup form, in this
    case adding the first and last name.
    """
    first_name = forms.CharField(label=_(u'First name'),
                             max_length=30,
                             required=False)

    last_name = forms.CharField(label=_(u'Last name'),
                            max_length=30,
                            required=False)
    field_order=['first_name','last_name']

您可以将它用于任何继承类Form的表单。

默认情况下 Form.field_order=None,它保留您在表单类中定义字段的顺序。如果 field_order 是字段名称列表,则字段按列表指定的顺序排序,其余字段根据默认顺序附加。

【讨论】:

谢谢!它完全按照您的描述工作。我正在使用 Django 1.11。【参考方案5】:

在较新的 Django 中,fields 属性是 collections.OrderedDict,从 Python 3.2 开始,has a new methodmove_to_end,所以你可以简单地:

class CustomForm(forms.Form):

    ...

    # Note the following must contain all the fields in the form in the order
    # you desire.
    CUSTOM_ORDER = ('field1', 'field2', 'field3')

    def __init__(self, *args, **kwargs):
        super(CustomForm, self).__init__(*args, **kwargs)

        # Use custom order for form fields.
        for field_name in CUSTOM_ORDER:
            self.fields.move_to_end(field_name)

【讨论】:

以上是关于重新排序模型表单字段的主要内容,如果未能解决你的问题,请参考以下文章

在提交表单之前重新排序输入

django模型表单ModelForm

如何重新排序 Django-Graphene 子查询?

仅设置表单提交时输入的字段的主干模型属性

通过拖放功能重新排序 Xamarin 表单中的 ListView

如何使用 jQuery 重新填充表单提交时隐藏的 CSV 字段