Python 如何指定Django表单中字段的顺序?
我们正在使用Django 2.2,我想升级到Django 3.0。我们有一个mixin(编写于2017年),它将字段添加到表单中:Python 如何指定Django表单中字段的顺序?,python,django,django-forms,modelform,django-3.0,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, **kwa
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, '')
self.get\u localized\u fields()
返回英文版的('first\u name\u en'、'last\u name\u en')
(按此顺序),或与我们使用的当前语言相同的本地化版本
此mixin用作从ModelForm
继承的表单的基类之一:
class RegistrationForm(AddAttributesToFieldsMixin, CleanEmailMixin, CleanNewPasswordMixin, CleanDateOfBirthMixin, LocalizedFirstLastNameMixin, forms.ModelForm):
....
class ProfileForm(AddAttributesToFieldsMixin, CleanDateOfBirthMixin, LocalizedFirstLastNameMixin, forms.ModelForm):
....
它适用于Django版本,最高可达2.2。但当我升级到3.0时,会收到以下错误消息:
AttributeError:“dict”对象没有属性“move\u to\u end”
此功能的信息:
将现有元素移动到末尾(如果last==False,则移动到开头)。
它属于OrderedDict
我想我们希望这些字段在表单字段的开头
Django 3.0中表单中字段的实现是否有变化?如何指定字段的顺序?如果我改变它,它会在以前的版本中工作吗,比如Django 2.2
我检查了从3.0.1到3.0.5的版本,也没有找到关于这个问题的任何文档
更新:我发现我可以调用self.order\u字段(…)
,但是如何定义来自模型的字段呢?我只想在字段列表的开头添加两个附加字段
表单中字段的实现是否有变化
Django 2.2和3之间的变化是声明字段的初始化方式:
- Django 2.2.12
- Django 3
我会将
self.fields
转换为OrderedDict
(基本上回到2.2版中的版本),以启用self.fields。再次移动到\u end
from collections import OrderedDict
class LocalizedFirstLastNameMixin(object):
def __init__(self, *args, **kwargs):
self.language_code = kwargs.pop('language_code', 'en')
super().__init__(*args, **kwargs)
self.fields = OrderedDict(self.fields)
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, '')
表单中字段的实现是否有变化
Django 2.2和3之间的变化是声明字段的初始化方式:
- Django 2.2.12
- Django 3
我会将
self.fields
转换为OrderedDict
(基本上回到2.2版中的版本),以启用self.fields。再次移动到\u end
from collections import OrderedDict
class LocalizedFirstLastNameMixin(object):
def __init__(self, *args, **kwargs):
self.language_code = kwargs.pop('language_code', 'en')
super().__init__(*args, **kwargs)
self.fields = OrderedDict(self.fields)
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, '')
OrderedDict
来自标准库
from collections import OrderedDict
而实例有。move_to_end()
,它只是说你的dict
对象没有。move_to_end()
,这意味着你在使用一个普通的dict。像这样将它转换成一个有序的dict
x = { "key" : "value"}
y = OrderedDict(x)
# OrderedDict([('key', 'value')])
现在
.move_to_end()
将起作用orderedICT
来自标准库
from collections import OrderedDict
而实例有。move_to_end()
,它只是说你的dict
对象没有。move_to_end()
,这意味着你在使用一个普通的dict。像这样将它转换成一个有序的dict
x = { "key" : "value"}
y = OrderedDict(x)
# OrderedDict([('key', 'value')])
现在.move_to_end()
将起作用我在中被要求不要自己操作字段的顺序,而是使用支持的API方法。因此,我更改了代码并使用了self.order\u字段
:
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)
请注意,我只对前两个字段进行排序。所有其他字段都保持默认顺序。我现在也不必按相反的顺序添加字段。我在中被要求不要自己操作字段的顺序,而是使用支持的API方法。因此,我更改了代码并使用了self.order\u字段
:
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)
请注意,我只对前两个字段进行排序。所有其他字段都保持默认顺序。我现在也不必按相反的顺序添加字段。谢谢你的建议。我在
\uuu init\uuuu
方法中定义了self.fields=OrderedDict(self.fields)
就在super()…
之后(我认为它不应该在for循环中),它可以工作。但是改变self.fields
的定义没有问题吗?我不这么认为,因为orderedict
是dict()的一个子类。我改变了主意,不能接受这个答案。请看我的答案。谢谢你的想法。我在\uuu init\uuuu
方法中定义了self.fields=OrderedDict(self.fields)
就在super()…
之后(我认为它不应该在for循环中),它可以工作。但是改变self.fields
的定义没有问题吗?我不这么认为,因为orderedict
是dict()的一个子类。我改变了主意,不能接受这个答案。请看我的答案。