質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

839閲覧

[Django] 編集画面で編集した内容がDBに反映されない

kawataku

総合スコア3

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/07/13 05:43

編集2021/07/13 06:41

前提・実現したいこと

一度登録したレコードを編集する画面において、編集した内容がDBに反映されるようにしたいです。

発生している問題・エラーメッセージ

まず最初にCreate部分の画面になります。この画面で作成したレコードはきちんとDBに反映されます。
旅行作成画面
次に、Update部分の画面になります。
編集画面
この場合は、旅行作成画面で入力した状態のまま変更を加えず、送信した場合になるのですが、
太陽などが消えて、空白の状態になってしまいます。

次は、新しくフォームを追加した状態になります。
新しくフォームを追加した状態
以下がPOST送信した時の状態になります。
新しくフォームを追加して送信した結果
この場合は、地球などが消えてしまい、空白になります。
さらに、費用を追加を押してないのに、費用を追加するフォームが追加されてしまいます。

また、補足としましては、Create画面にて入力したレコードがUpdate画面の初期値として、入力されているものとします。

該当のソースコード

forms.py
forms.py
文字数の関係で、forms.pyは画像にさせていただきました。

今回はSpot, Transport, Otherにて問題が起きていると思いますので、この3つのみを載せておきたいと思います。

views.py

django

1def edit(request, num): 2 other_model = Other.objects.filter(trip=trip_model.id) 3 spot_model = Spot.objects.filter(trip=trip_model) 4 spot_first_model = Spot.objects.filter(trip=trip_model).first() 5 transport_model = Transport.objects.filter(spot__in=spot_model) 6 7 OtherFormSet = forms.modelformset_factory( 8 Other, form=OtherForm, extra=0 9 ) 10 SpotFormSet = forms.modelformset_factory( 11 Spot, form=SpotForm, extra=0 12 ) 13 TransportFormSet = forms.modelformset_factory( 14 Transport, form=TransportForm, extra=0 15 ) 16 17 # idがnumのtripを取得する 18 if request.method == 'POST': 19 # 更新時は既に親モデルと繋がっている状態で渡されるから、いちいち外部キーを取得する必要はない 20 others = OtherFormSet(request.POST, queryset=other_model) 21 spots = SpotFormSet(request.POST, queryset=spot_model) 22 spot_first = SpotForm(request.POST, instance=spot_first_model) 23 transports = TransportFormSet(request.POST, queryset=transport_model) 24 # バリデーションのチェック 25 if others.is_valid() and spots.is_valid() and spot_first.is_valid() and transports.is_valid(): 26 trip.save() 27 # trip_id = Trip.objects.filter(id=num) 28 other = others.save() 29 for other_db in other: 30 other_db.trip = trip_model 31 other_db.save() 32 33 spot_first = spot_first.save() 34 35 spot = spots.save() 36 for spot_db in spot: 37 spot_db.trip = trip_model 38 spot_db.save() 39 40 # transport用にspotの情報を取得する 41 spot_id = Spot.objects.filter(trip=trip_model) 42 transport = transports.save() 43 for i in range(len(transport)): 44 transport[i].spot = spot_id[i] 45 transport[i].save() 46 47 return redirect(to='/make_trip/myPage') 48 49 # Getアクセス時の処理 50 else: 51 others = OtherFormSet(queryset=other_model) 52 spots = SpotFormSet(queryset=spot_model)[1:] 53 transports = TransportFormSet(queryset=transport_model) 54 spot_first = SpotForm(instance=spot_first_model) 55 56 params = { 57 'others': others, 58 'spots': spots, 59 'transports': transports, 60 'spot_first': spot_first, 61 'id': num, 62 } 63 return render(request, 'make_trip/edit.html', params)

modelformsetを使用しておりまして、複数のレコードを取得できるようにしております。

request.POSTでは無事に地球などを受け取れているのですが、spots = SpotFormSet(request.POST, queryset=spot_model)の中身を見てみたところ、入っておりませんでした。
以下がrequest.POSTの中身になります。

request.post: <QueryDict: {'csrfmiddlewaretoken': ['VJFLV1PvaaHvNYv8rWIfjQUkIr9iPVY6aMC6C5DSwDyKOzWtV6CFqe5dMQtbvQ83'], 'title': ['ベルウッド'], 'trip_name': ['宇宙旅行'], 'start': ['2021-07-09'], 'end': ['2021-07-23'], 'spot_name': ['砂丘'], 'spot_time': ['2021-07-16 11:05:00'], 'spot_cost': ['111'], 'form-TOTAL_FORMS': ['3', '3'], 'form-INITIAL_FORMS': ['2', '0'], 'form-MIN_NUM_FORMS': ['0', '0'], 'form-MAX_NUM_FORMS': ['1000', '1000'], 'form-0-transport_name': ['タクシー'], 'form-0-transport_time': ['2021-07-15 11:05:00'], 'form-0-transport_fee': ['3'], 'form-1-spot_name': ['空港'], 'form-1-spot_time': ['2021-07-22 11:05:00'], 'form-1-spot_cost': ['2'], 'form-1-transport_name': ['電車'], 'form-1-transport_time': ['2021-07-09 11:05:00'], 'form-1-transport_fee': ['111'], 'form-2-spot_name': ['地球'], 'form-2-spot_time': ['2021-07-23 11:05:00'], 'form-2-spot_cost': ['111'], 'form-3-transport_name': ['エレベーター'], 'form-3-transport_time': ['2021-07-16 11:34'], 'form-3-transport_fee': ['11'], 'form-3-spot_name': ['月'], 'form-3-spot_time': ['2021-07-13 12:15'], 'form-3-spot_cost': ['100']}>

template

django

1{% block container %} 2{% load boost %} 3<form action="{% url 'edit' id %}" method="post"> 4 {% csrf_token %} 5 {{ spot_first.spot_name }} 6 {{ spot_first.spot_time }} 7 {{ spot_first.spot_cost }} 8 <div id="tran_spot_total"> 9 {{ transports.management_form }} 10 {{ spots.management_form }} 11 <div id="tranSpot_formset"> 12 {% for transport, spot in transports|zip:spots %} 13 <div id="input-transport-form-{{ forloop.counter0 }}"> 14 {{ transport.transport_name }} 15 {{ transport.transport_time }} 16 {{ transport.transport_fee }} 17 </div> 18 <div class="row mb-5" id="input-spot-form-{{ forloop.counter0 }}"> 19 {{ spot.spot_name }} 20 {{ spot.spot_time }} 21 {{ spot.spot_cost }} 22 </div> 23 {% endfor %} 24 </div> 25 <div id="tranSpot"></div> 26 </div> 27 <button type="button" id="addSpot">観光地を追加</button> 28 <div id="other_total"> 29 {{ others.management_form }} 30 <div id="other_formset"> 31 {% for other in others %} 32 <div id="input-form-{{ forloop.counter0 }}"> 33 {{ other.extra_name }} 34 {{ other.extra_cost }} 35 </div> 36 {% endfor %} 37 </div> 38 <div id="extra"></div> 39 </div> 40 <button type="button" id="addExtra">費用を追加</button> 41 <button type="submit">完成!</button> 42</form> 43{% endblock %} 44 45{% block js %} 46<script> 47 $(function(){ 48 // transpot部分の処理 49 var TotalManageElement = $('input#id_form-TOTAL_FORMS'); 50 var currentCount = parseInt(TotalManageElement.val()); 51 $('#addSpot').on('click', function(){ 52 var new_tranSpot = `<div class="row justify-content-end mb-5" id="input-transport-form-0"> 53 <div class="col-2"><h1 class="text-light">↓</h1></div> 54 <div class="col-3"> 55 <input type="text" name="form-0-transport_name" class="form-control" placeholder="移動手段" maxlength="30" id="id_form-0-transport_name"> 56 </div> 57 <div class="col-3"> 58 <input type="text" name="form-0-transport_time" class="form-control smallDate" placeholder="乗る時間" autocomplete="off" id="id_form-0-transport_time"> 59 </div> 60 <div class="col-3"> 61 <input type="number" name="form-0-transport_fee" class="form-control costs" placeholder="料金" id="id_form-0-transport_fee"> 62 </div> 63 </div> 64 65 <div class="row mb-5" id="input-spot-form-0"> 66 <div class="col-4"> 67 <input type="text" name="form-0-spot_name" class="form-control" placeholder="観光地" maxlength="50" id="id_form-0-spot_name"> 68 </div> 69 <div class="col-4"> 70 <input type="text" name="form-0-spot_time" class="form-control smallDate" placeholder="到着時間" autocomplete="off" id="id_form-0-spot_time"> 71 </div> 72 <div class="col-4"> 73 <input type="number" name="form-0-spot_cost" class="form-control costs" placeholder="滞在料金" id="id_form-0-spot_cost"> 74 </div> 75 </div>` 76 currentCount += 1 77 new_tranSpot = new_tranSpot.replace(/form-0/g, 'form-'+currentCount); 78 $('#tranSpot').append(new_tranSpot); 79 TotalManageElement.attr('value', currentCount); 80 81 }); 82 // other部分の処理 83 $('#addExtra').on('click', function(){ 84 var new_code = `<div class="row mb-3" id="input-form-0"> 85 <div class="col-6"><input type="text" name="form-0-extra_name" class="form-control" placeholder="追加の費用の項目" maxlength="50" id="id_form-0-extra_name"></div> 86 <div class="col-6"><input type="number" name="form-0-extra_cost" class="form-control costs" placeholder="追加の費用" id="id_form-0-extra_cost"></div> 87 </div>` 88 new_code = new_code.replace(/form-0/g, 'form-'+currentCount); 89 $('#extra').append(new_code); 90 currentCount += 1 91 TotalManageElement.attr('value', currentCount); 92 }); 93 }); 94</script> 95{% endblock %}

spotstransportszipを使用することで、まとめて同じforの中で回しております。
また、観光地を追加費用を追加のボタンを押した場合は、JSの部分でフォームを追加するようにしております。

補足情報(FW/ツールのバージョンなど)

Python v3.7.7
Visual Studio Code v1.53.2
MacOS Darwin x64 20.3.0
Django 3.0.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問