我已經完成了ModelForm,在模型中添加了一些不是的額外字段。保存表單時,我使用這些字段進行一些計算。Django ModelForm帶有不在模型中的額外字段
額外的字段出現在表單上,並在上傳表單時在POST請求中發送。問題是我在驗證表單時沒有將它們添加到cleaned_data
字典中。我如何訪問它們?
我已經完成了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