DjangoでModelForm
を使用してデータベースのモデルのEditフォームを作成しています。ユーザーが1つのフィールドのみを編集したい場合は、フォームの各フィールドはオプションです。空のフィールドでモデルデータを保存するModelForm
私が午前問題は、私はビューでsave()
を呼び出すときに、任意の空のフィールドは、インスタンスの元の値の上に保存されていることである(例えば、私が唯一の新しいfirst_name
を入力すると、last_name
とecf_code
フィールドは空の文字列を保存します対応するインスタンスで)
形態:
class EditPlayerForm(forms.ModelForm):
class Meta:
model = Player
fields = ['first_name', 'last_name', 'ecf_code']
def __init__(self, *args, **kwargs):
super(EditPlayerForm, self).__init__(*args, **kwargs)
self.fields['first_name'].required = False
self.fields['last_name'].required = False
self.fields['ecf_code'].required = False
ビュー:
def view(request, player_pk = ''):
edit_player_form = forms.EditPlayerForm(auto_id="edit_%s")
if "edit_player_form" in request.POST:
if not player_pk:
messages.error(request, "No player pk given.")
else:
try:
selected_player = Player.objects.get(pk = player_pk)
except Player.DoesNotExist:
messages.error(request, "The selected player could not be found in the database.")
return redirect("players:management")
else:
edit_player_form = forms.EditPlayerForm(
request.POST,
instance = selected_player
)
if edit_player_form.is_valid():
player = edit_player_form.save()
messages.success(request, "The changes were made successfully.")
return redirect("players:management")
else:
form_errors.convert_form_errors_to_messages(edit_player_form, request)
return render(
request,
"players/playerManagement.html",
{
"edit_player_form": edit_player_form,
"players": Player.objects.all(),
}
)
フォームのsave()
メソッドをオーバーライドして、どのフィールドがPOST
リクエストの値を持っているかを明示的にチェックしようとしましたが、違いは見られませんでした。ドキュメントはModeForm
は、フォームの送信には存在しない値のためにこれらを使用すると言うように私もPlayer
モデルの任意のデフォルト値を持っていない
def save(self, commit = True):
# Tried this way to get instance as well
# instance = super(EditPlayerForm, self).save(commit = False)
self.cleaned_data = dict([ (k,v) for k,v in self.cleaned_data.items() if v != "" ])
try:
self.instance.first_name = self.cleaned_data["first_name"]
except KeyError:
pass
try:
self.instance.last_name = self.cleaned_data["last_name"]
except KeyError:
pass
try:
self.instance.ecf_code = self.cleaned_data["ecf_code"]
except KeyError:
pass
if commit:
self.instance.save()
return self.instance
:saveメソッドをオーバーライドすることで
試み。
編集:ここでは
が全体EditPlayerForm
次のとおりです。
class EditPlayerForm(forms.ModelForm):
class Meta:
model = Player
fields = ['first_name', 'last_name', 'ecf_code']
def __init__(self, *args, **kwargs):
super(EditPlayerForm, self).__init__(*args, **kwargs)
self.fields['first_name'].required = False
self.fields['last_name'].required = False
self.fields['ecf_code'].required = False
def save(self, commit = True):
# If I print instance variables here they've already
# been updated with the form values
self.cleaned_data = [ k for k,v in self.cleaned_data.items() if v ]
self.instance.save(update_fields = self.cleaned_data)
if commit:
self.instance.save()
return self.instance
EDIT:
[OK]をので、ここでは、溶液中で、私はそれが役に立つかもしれないと私はここにそれを置くだろう考え出し他の人(私は確かにこれから少し学んだ)。
モデルフォームのis_valid()
メソッドは、フォームに渡すインスタンスを実際に変更して、save()
メソッドでフォームを保存する準備が整いました。したがって、この問題を解決するために、私は、フォームのclean()
方法を拡張:
def clean(self):
if not self.cleaned_data.get("first_name"):
self.cleaned_data["first_name"] = self.instance.first_name
if not self.cleaned_data.get("last_name"):
self.cleaned_data["last_name"] = self.instance.last_name
if not self.cleaned_data.get("ecf_code"):
self.cleaned_data["ecf_code"] = self.instance.ecf_code
これは、基本的にはフィールドが空のフィールドが空の場合、からの既存の値とそれを埋めるかどうかを確認し与えられたインスタンス。 clean()
はインスタンス変数が新しいフォーム値で設定される前に呼び出されます。このように、空のフィールドはすべて、対応する既存のインスタンスデータで実際に埋められました。
ありがとうございました!私はこれをフォームの 'save()'メソッドに入れましたが、まだ動作していません。フォームのsaveメソッドの開始時にインスタンス変数を出力すると、それらはすでに空の文字列値に設定されています'instance.save()'もフォームのメソッドで呼び出されます(意味が成就してほしいと思っています) – RHSmith159
@ RHSmith159これは助けにならなかったので、 'EditPlayerForm'フォームを質問に追加できますか? – PRMoureu
確かに、私は今すぐ追加します – RHSmith159