モデルにされないのフィールドを追加してModelFormを実行しました。フォームを保存するときに、これらのフィールドをいくつかの計算に使用します。
追加のフィールドがフォームに表示され、フォームのアップロード時にPOSTリクエストで送信されます。問題は、フォームを検証するときにcleaned_data
辞書に追加されないことです。どうすればそれらにアクセスできますか?
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属性で「タプルにタプル(「リスト」ではなく)のみ連結できる」エラーが発生しました。それをタプルに変更して動作しました。
必要なすべてのことを実行したように見えることを除いて、非常によく似た問題がありましたが、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())
ここで手元にある質問には回答していませんが(既によく回答されています)、他の人を助けるかもしれません。
まず、artist_idとartistフィールドは必要ありません。それらはモデルから構築されます。アーティスト名が必要な場合は、artist_nameフィールド、つまりCharFieldを追加します。
さらに、あなたはclean_data内のclean_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は発生しませんが、余分なフィールドがcleaned_data辞書にないため、値はNoneに設定されます。
これがコードです。テンプレートにはオートコンプリートがあるため、フォームには、CharFieldとしてレンダリングされた「artist」フィールドと、指定されたアーティストIDで自動入力される非表示のIntegerFieldがあります。 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 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')
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",
)