![](/img/trans.png)
[英]Django - Accessing extra ModelForm fields in a different template
[英]Django ModelForm with extra fields that are not in the model
我做了一個 ModelForm,添加了一些模型中沒有的額外字段。 保存表單時,我將這些字段用於一些計算。
額外的字段出現在表單上,並在上傳表單時在 POST 請求中發送。 問題是當我驗證表單時,它們沒有添加到cleaned_data
字典中。 我怎樣才能訪問它們?
可以使用額外的字段擴展 Django ModelForm
。 想象一下你有一個自定義的 User 模型和這個ModelForm
:
class ProfileForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'country', 'website', 'biography']
現在,假設您想要包含一個額外的字段(不存在於您的 User 模型中,例如圖像頭像)。 通過執行以下操作擴展您的表單:
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 屬性中收到“只能將元組(不是“列表”)連接到元組”錯誤。 將其更改為元組並且它起作用了。
我有一個非常相似的問題,只是看起來我做了所有必需的事情,但是當 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())
不在這里回答手頭的問題(已經回答得很好),但可能會幫助其他人。
首先在表單中添加字段
class CreateForm(forms.ModelForm):
extra_field = forms.CharField(label = 'extra_field', required = False)
現在,在清理數據時,您需要從 self.data NOT self.cleaned_data 檢索額外的字段
正確:
self.data.get('extra_field')
錯誤:
self.cleaned_data.get('extra_field')
首先,你不應該有artist_id 和artist 字段。 它們是從模型構建的。 如果您需要一些藝術家姓名,請添加 Artist_name 字段,即CharField 。
此外,您正在嘗試從 clean_data 中的 clean 值中檢索某些內容。 可能沒有您需要的數據 - 您應該使用 self.data 中的值,其中數據直接來自 POST。
這個答案對於原始海報來說可能為時已晚,但我認為它可能對其他人有所幫助。 我遇到了同樣的問題,我確實注意到 self.cleaned_data('artist_id') 可以在 clean() 方法中訪問,但不能在 clean_artist() 中訪問。
當我在 Meta 的“字段”聲明中添加額外的字段時,它就起作用了。
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字典中。
這是代碼。 在模板中有一個自動完成功能,因此在表單中有一個呈現為 CharField 的“藝術家”字段和一個隱藏的 IntegerField,它將使用給定的藝術家 ID 自動填充。 在 clean_artist 方法中,我想選擇藝術家對象並將其存儲在表單的藝術家字段中。
模型.py
class Music(models.Model):
artist = models.ForeignKey(Artist, related_name='music', blank=True, null=True)
# other fields...
表格.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
在 Django 2 中,您可以添加字段,因為它是一個普通表單
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",
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.