我已经创建了一个ModelForm并添加了一些不在模型中的额外字段。当保存表单时,我使用这些字段进行一些计算。
这些额外的字段会出现在表单上,并且在上传表单时作为POST请求发送。问题是,当我验证表单时,它们未被添加到cleaned_data
字典中。我该如何访问它们?
我已经创建了一个ModelForm并添加了一些不在模型中的额外字段。当保存表单时,我使用这些字段进行一些计算。
这些额外的字段会出现在表单上,并且在上传表单时作为POST请求发送。问题是,当我验证表单时,它们未被添加到cleaned_data
字典中。我该如何访问它们?
在 Django 2+ 中,您可以像这样添加额外的字段:
class ProfileForm(forms.ModelForm):
extra_field = forms.ImageField()
class Meta:
model = User
fields = ['username', 'country', 'website', 'biography']
可以通过添加额外字段来扩展Django ModelForm
。假设您有一个自定义的用户模型和这个ModelForm
:
class ProfileForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'country', 'website', 'biography']
现在,想象一下你想要包含一个额外的字段(不在你的用户模型中,比如说一个图像头像)。通过以下方式扩展你的表单:
from django import forms
class AvatarProfileForm(ProfileForm):
profile_avatar = forms.ImageField()
class Meta(ProfileForm.Meta):
fields = ProfileForm.Meta.fields + ('profile_avatar',)
最后(假设表单中有一个 ImageField
),在视图中实例化表单时,请记得包含 request.FILES
:
# (view.py)
def edit_profile(request):
...
form = AvatarProfileForm(
request.POST or None,
request.FILES or None,
instance=request.user
)
...
my_new_field
ж·»еЉ е€°fields
е€—иЎЁдёж—¶пјЊе‡єзЋ°дє†django.core.exceptions.FieldError: Unknown field(s) (my_new_field) specified for MyModel
错误。 Django 1.10版本。 - CpILLTypeError: can only concatenate list (not "tuple") to list
错误。
你应该将第二个类表单中的 field
更改为列表格式。 - Ali Irani我遇到了一个非常类似的问题,尽管看起来我已经做了所有必要的事情,但在 Django 启动时我仍然收到了这个错误:
django.core.exceptions.FieldError: Unknown field(s) (my_new_field) specified for MyModel
这是我的一个愚蠢错误,我不小心使用了 Widget 类来声明我的字段:
class MyForm(forms.ModelForm):
my_new_field = forms.HiddenInput()
用一个字段(Field)类来代替:
class MyForm(forms.ModelForm):
my_new_field = forms.CharField(widget=forms.HiddenInput())
这里不回答手头的问题(因为已经有很好的答案了),但可能会对其他人有所帮助。
forms.CheckboxInput()
添加一个字段,但实际上需要使用 forms.BooleanField()
。 - zoidberg首先在表单中添加字段
class CreateForm(forms.ModelForm):
extra_field = forms.CharField(label = 'extra_field', required = False)
现在,在清理数据时,您需要从self.data中检索额外的字段,而不是self.cleaned_data。
正确的做法:
self.data.get('extra_field')
错误:
self.cleaned_data.get('extra_field')
首先,你不应该有artist_id和artist字段。它们是从模型构建的。如果你需要某个艺术家的名字,请添加artist_name字段,它是CharField。
此外,在clean value中尝试从cleaned_data中检索某些数据可能不存在。你应该使用self.data中的值,其中包含直接来自POST的数据。
这个答案可能对原帖发布者来说已经太晚了,但我认为它可能会帮助其他人。我遇到了同样的问题,并注意到self.cleaned_data('artist_id')可以在clean()方法中访问,但不能在clean_artist()方法中访问。
当我在Meta的'fields'声明中添加了额外的字段时,它就起作用了。
class Meta:
model = Music
fields=[..., 'artist_id']
您应该可以在clean_artist()函数中访问self.cleaned_data('artist_id')。
好的,我已经解决了。似乎使用cleaned_data ['field_name']访问额外字段会引发KeyError,但是使用cleaned_data.get('field_name')可以工作。这很奇怪,因为模型的常规字段可以通过cleaned_data ['field_name']访问。
更新:不,它不起作用。使用get()不会引发KeyError,但它会将值设置为None,因为额外字段不在cleaned_data字典中。
这是代码。在模板中有一个自动完成,因此在表单中有一个“artist”字段呈现为CharField和一个隐藏的IntegerField,它将自动填充给定艺术家的ID。在clean_artist方法中,我想选择艺术家对象并将其存储在表单的艺术家字段中。
models.py
class Music(models.Model):
artist = models.ForeignKey(Artist, related_name='music', blank=True, null=True)
# other fields...
forms.py
class MusicForm(forms.ModelForm):
artist_id = forms.IntegerField(label="", widget=forms.HiddenInput(), required=False)
artist = forms.CharField(required=False)
# other fields ...
class Meta:
model = Music
def clean_artist(self):
if self.cleaned_data.get('artist') == '':
artist = None
else:
artist_id = self.cleaned_data.get('artist_id') # this returns always None because artist_id is not in cleaned_fields (this seemed to work with previous django versions but not with current SVN version)
if artist_id != None:
artist = Artist.objects.get(id=artist_id)
else:
artist = None
return artist
class CreateCompanyForm(forms.ModelForm):
password_confirmation = forms.CharField(
label=translate('Password confirmation'),
max_length=70,
widget=forms.PasswordInput(),
required=True,
)
company_name = forms.CharField(
label="Nombre de la Compañía",
max_length=90,
widget=forms.TextInput(),
required=True,
)
class Meta:
model = AppUser
fields = (
"email",
"first_name",
"last_name",
"password",
)
我遇到了类似的问题,但在我的情况下,似乎额外的字段没有通过验证。这就是它未出现在表单的cleaned_data中的原因。