Django ModelForm带有不在模型中的额外字段
我已经完成了ModelForm,在模型中添加了一些不是的额外字段。保存表单时,我使用这些字段进行一些计算。Django ModelForm带有不在模型中的额外字段
额外的字段出现在表单上,并在上传表单时在POST请求中发送。问题是我在验证表单时没有将它们添加到cleaned_data
字典中。我如何访问它们?
好的我已经解决了。看起来,使用cleared_data ['field_name']访问额外的字段引发了一个KeyError,但使用的清洁数据.get('field_name')的作品。这很奇怪,因为模型的正常字段可以通过cleared_data ['field_name']来访问。
更新:不,它不起作用。使用get()它不会引发KeyError,但它将值设置为None,因为额外的字段不在clean_data字典中。
这是代码。在模板中有一个自动完成,所以在表单中有一个呈现为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
这很奇怪,因为get不是不同于 []。发布你的代码,它会更容易找到潜在的问题。 – gruszczy 2010-02-09 13:48:57
回报艺术家需要额外的缩进。它不在clean_artist方法中。 – 2010-02-09 16:34:43
做了缩进修复问题? – Anentropic 2011-04-21 15:23:19
首先,你不应该有artist_id和艺术家领域。它们是从模型构建的。如果您需要某个艺术家名称,请添加artist_name字段,即CharField。
此外,您正尝试从clean_data内部清除值中检索某些内容。可能没有您需要的数据 - 您应该使用self.data中的值,其中数据直接来自POST。
实际上,在单独的clean_X方法中使用cleared_data是正确的:http://docs.djangoproject.com/zh/dev/ref/forms/validation/#cleaning-a-specific-field-attribute – Anentropic 2011-04-21 15:22:41
感谢版,@Martin – Cartucho 2017-12-20 12:57:09
可以用额外的字段扩展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
)
...
希望它能帮助。祝你好运!
编辑:
我得到一个“只能串联元组(没有‘名单’),以元组”错误AvatarProfileForm.Meta.fields属性。将它更改为一个元组,它工作。
当我将'my_new_field'添加到'fields'列表时,我得到'django.core.exceptions.FieldError:为MyModel指定的未知字段(my_new_field)。 Django 1.10 – CpILL 2017-01-31 02:21:19
这个答案对原始海报来说可能太晚了,但我认为这可能对别人有帮助。我有同样的问题,我注意到可以在clean()方法中访问self.cleaned_data('artist_id'),但不能在clean_artist()中访问。
当我在Meta的'fields'声明中添加额外的字段时,它就起作用了。
class Meta:
model = Music
fields=[..., 'artist_id']
您应该可以访问clean_artist()中的self.cleaned_data('artist_id')。
应将它们添加到cleared_data字典中。请张贴您的表格代码,以便我们可以看一看。 – gruszczy 2010-02-09 12:55:01
我建议你不要在Form域中存储信息。更清晰的解决方案是:将其存储在会话中。 – sergzach 2012-05-22 10:32:28
如果您在后续答案中发布的代码是精确的复制粘贴,那么最后一行有一个缩进问题 - 它应该是一级。 – 2010-02-09 16:27:24