如何指定 Django 表单中的字段顺序?

Uri*_*Uri 3 python django django-forms modelform django-3.0

我们正在使用 Django 2.2,我想升级到 Django 3.0。我们有一个 mixin(写于 2017 年),可以向表单添加字段:

class LocalizedFirstLastNameMixin(object):
    def __init__(self, *args, **kwargs):
        self.language_code = kwargs.pop('language_code', 'en')
        super().__init__(*args, **kwargs)
        for loc_field in reversed(self.get_localized_fields()):
            self.fields[loc_field] = User._meta.get_field(loc_field).formfield()
            self.fields[loc_field].required = True
            self.fields.move_to_end(loc_field, last=False)
            self.initial[loc_field] = getattr(self.instance, loc_field, '')
Run Code Online (Sandbox Code Playgroud)

self.get_localized_fields()返回('first_name_en', 'last_name_en')(按此顺序)英语版本,或本地化为我们正在使用的当前语言的相同版本。

该 mixin 用作继承自以下形式的基类之一ModelForm

class RegistrationForm(AddAttributesToFieldsMixin, CleanEmailMixin, CleanNewPasswordMixin, CleanDateOfBirthMixin, LocalizedFirstLastNameMixin, forms.ModelForm):
    ....

class ProfileForm(AddAttributesToFieldsMixin, CleanDateOfBirthMixin, LocalizedFirstLastNameMixin, forms.ModelForm):
    ....
Run Code Online (Sandbox Code Playgroud)

它适用于 Django 2.2 版本。但是当我升级到3.0时,我收到以下错误消息:

AttributeError: 'dict' object has no attribute 'move_to_end'

该函数的信息:

Move an existing element to the end (or beginning if last==False).

并且它属于OrderedDict.

所以我想我们希望这些字段位于表单字段的开头。

Django 3.0 中表单字段的实现是否有变化以及如何指定字段的顺序?如果我更改它,它可以在以前的版本(例如 Django 2.2)中工作吗?

我检查了Django 3.0 发行说明以及从 3.0.1 到 3.0.5 的版本,但没有找到有关此问题的任何文档。

更新:我发现我可以调用self.order_fields(...),但是如何定义来自模型的字段?我只想在字段列表的开头添加两个附加字段。

Uri*_*Uri 5

我在Django 开发人员邮件列表中询问,他们告诉我不要自己操作字段的顺序,而是使用此处记录的受支持的 API 方法。所以我更改了代码并改为使用self.order_fields

class LocalizedFirstLastNameMixin(object):
    def __init__(self, *args, **kwargs):
        self.language_code = kwargs.pop('language_code', 'en')
        super().__init__(*args, **kwargs)
        localized_fields = self.get_localized_fields()
        for loc_field in localized_fields:
            self.fields[loc_field] = User._meta.get_field(loc_field).formfield()
            self.fields[loc_field].required = True
            self.initial[loc_field] = getattr(self.instance, loc_field, '')
        self.order_fields(field_order=localized_fields)
Run Code Online (Sandbox Code Playgroud)

请注意,我只对前两个字段进行排序。所有其他字段均保留默认顺序。我现在也不必以相反的顺序添加字段。