85519


お世話になります。

サッカーゲームの選手閲覧作成を目指して、作成を行っております。

現在、管理画面上で登録した初期値情報をHTMLのform上で出力する所までは行っているのですが、  
保存登録でsubmitボタンを押しても、保存されず、画面遷移しないという事象が起こっております。

もしお分かりの方が居られましたら、  
どの点でエラーが生じているかアドバイス頂けると幸いです。

宜しくお願いいたします。

参考文献：  
<https://blog.narito.ninja/detail/33/>  
<https://blog.narito.ninja/detail/35>

・今わかっているエラー内容：  
保存登録のsubmitボタンを押下後、formのformationformsetが画像無しで表示されている。

保存登録のsubmitボタンを押す前  
[![画像の説明をここに入力](https://i.stack.imgur.com/Jim9J.png)](https://i.stack.imgur.com/Jim9J.png)

保存登録のsubmitボタンを押下後  
[![画像の説明をここに入力](https://i.stack.imgur.com/15pUL.png)](https://i.stack.imgur.com/15pUL.png)

**form.py**

[code]

    class PlayerCreateForm(forms.ModelForm):
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            for field in self.fields.values():
                field.widget.attrs['class'] = 'form-control'
    
        class Meta:
            model =  Player
            exclude = ('skill',)
    
    
    SkillInlineFormSet = forms.inlineformset_factory(
        Player, Player.skill.through, fields='__all__', can_delete=False
    )
    
    AbilityFormSet = forms.inlineformset_factory(
        Player, Ability, fields='__all__', extra=0
    )
    
    FormationFormSet = forms.inlineformset_factory(
        Player, Formation, fields='__all__', extra=0
    )
    
[/code]

**views.py**

[code]

    def editformview(request, pk):
        player = get_object_or_404(Player, pk=pk)
        form = PlayerCreateForm(request.POST or None, files=request.FILES or None, instance=player)
        skillformset = SkillInlineFormSet(request.POST or None, instance=player)
        abilityformset = AbilityFormSet(request.POST or None, instance=player)
        formationformset = FormationFormSet(request.POST or None, files=request.FILES or None, instance=player)
        if request.method == 'POST' and form.is_valid() and skillformset.is_valid() and abilityformset.is_valid() and formationformset.is_valid():
            form.save()
            skillformset.save()
            abilityformset.save()
            formationformset.save()
            return redirect('mainapp:index')
    
        context = {
            'form': form,
            'skillformset': skillformset,
            'abilityformset': abilityformset,
            'pk':pk,
            'formationformset': formationformset,
        }
    
        return render(request, 'mainapp/editform.html', context)
    
[/code]

**editform.html**

[code]

    <div class="row">
      <div class="card card-profile my-5 mx-auto">
        <div class="card-body">
          <form method="post" action="{% url 'editform' pk %}" enctype="multipart/form-data">
            <h5 class="card-title text-center">選手プロフィール編集</h5>
            {% csrf_token %}
            <table class="profile_table mb-4">
              <tbody>
                <tr>
                  <th class="header">選手画像</th>
                  <td class="data">{{ form.player_image }}</td>
                </tr>
                <tr>
                  <th class="header">リリース日</th>
                  <td class="data form_wrap form_wrap-2">{{ form.date_field }}</td>
                </tr>
                <tr>
                  <th class="header">選手名</th>
                  <td class="data form_wrap form_wrap-2">{{ form.player_name }}</td>
                </tr>
                <tr>
                  <th class="header">初期能力/最大能力</th>
                  <td class="data form_wrap form_wrap-2">
                    <div class="row">
                      <div class="col">{{ form.initial }}</div>
                      <div class="col">{{ form.maximum }}</div>
                    </div>
                  </td>
                </tr>
                <tr>
                  <th class="header">最大レベル</th>
                  <td class="data form_wrap form_wrap-2">{{ form.level }}</td>
                </tr>
                <tr>
                  <th class="header">レアリティ</th>
                  <td class="data form_wrap form_wrap-2">{{ form.rarity_group }}</td>
                </tr>
                <tr>
                  <th class="header">ポジション</th>
                  <td class="data form_wrap form_wrap-2">{{ form.position_group }}</td>
                </tr>
                <tr>
                  <th class="header">所属リーグ</th>
                  <td class="data form_wrap form_wrap-2">{{ form.league_group }}</td>
                </tr>
                <tr>
                  <th class="header">所属クラブ</th>
                  <td class="data form_wrap form_wrap-2">{{ form.club_group }}</td>
                </tr>
                <tr>
                  <th class="header">国名</th>
                  <td class="data form_wrap form_wrap-2">{{ form.country }}</td>
                </tr>
                <tr>
                  <th class="header">年齢</th>
                  <td class="data form_wrap form_wrap-2">{{ form.age }}</td>
                </tr>
                <tr>
                  <th class="header">身長</th>
                  <td class="data form_wrap form_wrap-2">{{ form.height }}</td>
                </tr>
                <tr>
                  <th class="header">利き足</th>
                  <td class="data form_wrap form_wrap-2">{{ form.dominant_foot }}</td>
                </tr>
                <tr>
                  <th class="header">プレースタイル</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ form.playstyle_group }}
                  </td>
                </tr>
              </tbody>
            </table>
            <h5 class="card-title text-center">能力編集</h5>
            <table class="profile_table mb-4">
              <tbody>
            {{ abilityformset.management_form }}
            {% for ability_form in abilityformset %}
                <tr>
                  <th class="header">オフェンスセンス</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.offense_sense }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ボールコントロール</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.ball_control }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ドリブル</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.dribble }}
                  </td>
                </tr>
                <tr>
                  <th class="header">フライパス</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.fly_pass }}
                  </td>
                </tr>
                <tr>
                  <th class="header">決定力</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.determining_power }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ヘディング</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.heading }}
                  </td>
                </tr>
                <tr>
                  <th class="header">プレースキック</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.place_kick }}
                  </td>
                </tr>
                <tr>
                  <th class="header">カーブ</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.curve }}
                  </td>
                </tr>
                <tr>
                  <th class="header">スピード</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.speed }}
                  </td>
                </tr>
                <tr>
                  <th class="header">瞬発力</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.instantaneous_power }}
                  </td>
                </tr>
                <tr>
                  <th class="header">キック力</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.kick_power }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ジャンプ力</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.jumping }}
                  </td>
                </tr>
                <tr>
                  <th class="header">フィジカルコンタクト</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.physical_contact }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ボディコントロール</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.body_control }}
                  </td>
                </tr>
                <tr>
                  <th class="header">体力</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.physical_fitness }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ディフェンスセンス</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.defense_sense }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ボール奪取</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.take_the_ball }}
                  </td>
                </tr>
                <tr>
                  <th class="header">アグレッシブネス</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.aggressiveness }}
                  </td>
                </tr>
                <tr>
                  <th class="header">GKセンス</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.gksense }}
                  </td>
                </tr>
                <tr>
                  <th class="header">キャッチング</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.catching }}
                  </td>
                </tr>
                <tr>
                  <th class="header">クリアリング</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.clearing }}
                  </td>
                </tr>
                <tr>
                  <th class="header">コブラシング</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.cobraging }}
                  </td>
                </tr>
                <tr>
                  <th class="header">キック力</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.kick_power }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ディフレクティング</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.deflectiveing }}
                  </td>
                </tr>
                <tr>
                  <th class="header">逆足頻度</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.reverse_foot_frequency }}
                  </td>
                </tr>
                <tr>
                  <th class="header">逆足頻度</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.reverse_foot_accuracy }}
                  </td>
                </tr>
                <tr>
                  <th class="header">コンディション安定度</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.condition_stability }}
                  </td>
                </tr>
                <tr>
                  <th class="header">ケガ耐性</th>
                  <td class="data form_wrap form_wrap-2">
                    {{ ability_form.injury_resistance }}
                  </td>
                </tr>
            {% endfor %}
              </tbody>
            </table>
            <h5 class="card-title text-center">フォーメーション編集</h5>
            <table class="profile_table mb-4">
              <tbody>
              {{ formationformset.management_form }}
              {% for formation_form in formationformset %}
                <tr>
                  <th class="header">フォーメーション画像</th>
                  <td class="data">{{ formation_form.formation_images }}</td>
                </tr>
              {% endfor %}
              </tbody>
            </table>
            <h5 class="card-title text-center">スキル編集</h5>
            <table class="profile_table mb-4">
              <tbody>
                {{ skillformset.management_form }}
                {% for skill_form in skillformset %}
                <tr>
                  <th class="header">スキル</th>
                  <td class="data">{{ skill_form.skill }}</td>
                </tr>
                {% endfor %}
              </tbody>
            </table>
            <button class="btn btn-lg btn-warning btn-block" type="submit">登録する</button>
          </form>
        </div>
      </div>
    </div>
    
[/code]

**今わかっているエラー内容への対処：**  
現在、formではinlineformset_factoryを使用している為、ModelFormに変更。  
変更後に、初期値が渡されなかった為、断念致しました。

**form.py 変更後**

[code]

    class FormationCreateForm(forms.ModelForm):
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            for field in self.fields.values():
                field.widget.attrs['class'] = 'form-control'
    
        class Meta:
            model =  Formation
            fields='__all__'
    
[/code]

**views.py 変更後**

[code]

    formationform = FormationCreateForm(request.POST or None, files=request.FILES or None, instance=player)
        if request.method == 'POST' and form.is_valid() and skillformset.is_valid() and abilityformset.is_valid() and formationform.is_valid():
            form.save()
            skillformset.save()
            abilityformset.save()
            formationform.save()
            # 編集ページを再度表示
            return redirect('mainapp:index')
    
[/code]

**edit.html 変更後**

[code]

    <h5 class="card-title text-center">フォーメーション編集</h5>
    <table class="profile_table mb-4">
      <tbody>
        <tr>
          <th class="header">フォーメーション画像</th>
          <td class="data">{{ formationform.formation_images }}</td>
        </tr>
      </tbody>
    </table>
    
[/code]

**※追加※views.pyの各種formをデバッグ表示**

**デバッグ表示の為、viewsを変更**

[code]

    def editformview(request, pk):
        player = get_object_or_404(Player, pk=pk)
        form = PlayerCreateForm(request.POST or None,
                                files=request.FILES or None, instance=player)
        skillformset = SkillInlineFormSet(request.POST or None, instance=player)
        abilityformset = AbilityFormSet(request.POST or None, instance=player)
        formationformset = FormationFormSet(
            request.POST or None, files=request.FILES or None, instance=player)
        if request.method == 'POST' and form.is_valid():
            player = form.save(commit=False)
            logging.debug(player)
            if skillformset.is_valid():
                skill = skillformset.save(commit=False)
                logging.debug(skill)
                if abilityformset.is_valid():
                   ability = abilityformset.save(commit=False)
                   logging.debug(ability)
                   if formationformset.is_valid():
                       formationformset.save()
                       player.save()
                       skill.save()
                       ability.save()
                       logging.debug(formationformset)
                       
                       return redirect('index')　＃redirect先が誤っていた為、変更
    
[/code]

**views変更後のコンソール表示**

[code]

    System check identified no issues (0 silenced).
    January 04, 2022 - 13:20:57
    Django version 3.1.4, using settings 'e_football2022.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CONTROL-C.
    [04/Jan/2022 13:21:02] "GET /detail/1/editform/ HTTP/1.1" 200 52473
    [04/Jan/2022 13:21:07] "GET /detail/1/editform/ HTTP/1.1" 200 52473　
    2022-01-04 13:21:13,095 DEBUG キリアン・ムバッペ　　　　　　　⇦　＃　logging.debug(player)
    [04/Jan/2022 13:21:13] "POST /detail/1/editform/ HTTP/1.1" 200 52114
    
[/code]


CC BY-SA 4.0
2022-01-03T11:54:41.710
85463
2022-01-06T09:49:41.217
2022-01-06T09:40:47.213
48697
48697
question
python html django
Djangoのeditformにて保存が出来ない為、どの点でエラーが発生しているか知りたい。

[code]

    if skillformset.is_valid():
    
[/code]

ここのコードは実行してないため、skillformset のデータに不備があるはずなので、  
この if に以下の else を追加して、エラー情報を出力してみてください。

[code]

    else:
       print(skillformset.errors.as_text())
    
[/code]


CC BY-SA 4.0
2022-01-04T08:32:28.313
85481
2022-01-04T12:33:13.183
2022-01-04T12:33:13.183
3060
35698
85463
answer


※解決方法  
**errorform内容の確認 views.py**

[code]

    if skillformset.is_valid():
        pass
    else:
        print(skillformset.errors)
    
[/code]

**エラー内容**

[code]

    [{'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {'id': ['このフィールドは必須です。'], '__all__': ['この Player と Skill を持った Player-skill の関連 が既に存在します。']}, {}, {}, {}]
    [04/Jan/2022 21:46:06] "POST /detail/1/editform/ HTTP/1.1" 200 52114
    
[/code]

**解決方法 editform.html**  
参考文献：  
<https://teratail.com/questions/283685#reply-403501>

[code]

    <h5 class="card-title text-center">スキル編集</h5>
    <table class="profile_table mb-4">
      <tbody>
        {{ skillformset.management_form }}
        {% for skill_form in skillformset %}
        <tr>
          <th class="header">{{ skill_form.id }}</th> ＃追加
          <td class="data">{{ skill_form.skill }}</td>
        </tr>
        {% endfor %}
      </tbody>
    
[/code]


CC BY-SA 4.0
2022-01-06T09:42:25.193
85519
2022-01-06T09:49:41.217
2022-01-06T09:49:41.217
3060
48697
85463
answer