2017-12-11 19 views
-1

フォームとビューを使用してformset extraフィールドのデータを保存しようとしています。 例:-Teamにはプレーヤーがありません。だから私は新しいプレーヤーを追加したいと思っています。私は一度に複数のプレーヤーを追加する場合、問題はそれだけで o/p for below codeフォームとビューを使用してdjangoの動的フォームセットデータを保存するには

models.py

from django.db import models 

class Player(models.Model): 
    pname = models.CharField(max_length=50) 
    hscore = models.IntegerField() 
    age = models.IntegerField() 
    def __str__(self): 
     return self.pname 

class Team(models.Model): 
    tname = models.CharField(max_length=100) 
    player= models.ManyToManyField(Player) 
    def __str__(self): 
     return self.tname 

forms.py

from django import forms 
from django.forms.formsets import formset_factory 

class PlayerForm(forms.Form): 
    pname = forms.CharField() 
    hscore= forms.IntegerField() 
    age = forms.IntegerField() 

PlayerFormset= formset_factory(PlayerForm) 

class TeamForm(forms.Form): 
    tname= forms.CharField() 
    player= PlayerFormset() 

ビュー最後のオブジェクト値を保存している...です.py

from django.shortcuts import render, get_object_or_404,redirect 
from .models import Player,Team 
from .forms import TeamForm,PlayerFormset 
from django.contrib import messages 
from django.contrib.auth.decorators import login_required 
from django import forms 
from django.forms import formset_factory 

def post(request): 

    if request.POST: 
     form = TeamForm(request.POST) 
     form.player_instances = PlayerFormset(request.POST) 
     if form.is_valid(): 
     team= Team() 
     team.tname= form.cleaned_data['tname'] 
     team.save() 

     if form.player_instances.cleaned_data is not None: 

      for item in form.player_instances.cleaned_data: 
       player = Player() 
       player.pname= item['pname'] 
       player.hscore= item['hscore'] 
       player.age= item['age'] 
       player.save() 
       team.player.add(player) 
      team.save() 

    else: 
     form = TeamForm() 
     return render(request, 'new.html', {'form':form}) 

テンプレート:new.html

<html> 
<head> 

    <title>gffdfdf</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 

</head> 
<body> 

<div class="container"> 

<form action="" method="post" class=""> 
{% csrf_token %} 
    <h2> Team</h2> 
    {% for field in form %} 
    {{ field.errors }} 
    {{ field.label_tag }} : {{ field }} 
    {% endfor %} 
    {{ form.players.management_form }} 

    <h3> Product Instance(s)</h3> 
    <table id="table-product" class="table"> 
    <thead> 
     <tr> 
      <th>player name</th> 
     <th>highest score</th> 
     <th>age</th> 
     </tr> 

    </thead> 
     {% for player in form.players %} 
     <tbody class="player-instances"> 

    <tr> 
     <td>{{ player.pname }}</td> 
     <td>{{ player.hscore }}</td> 
     <td>{{ player.age }}</td> 
     <td> <input id="input_add" type="button" name="add" value=" Add More " class="tr_clone_add btn data_input"> </td> 
     </tr> 

     </tbody> 
{% endfor %} 
    </table><button type="submit" class="btn btn-primary">save</button> 

    </form> 
    </div> 
    <script> 
     var i = 1; 
    $("#input_add").click(function() { 
     $("tbody tr:first").clone().find(".data_input").each(function() { 
      if ($(this).attr('class')== 'tr_clone_add btn data_input'){ 
       $(this).attr({ 
        'id': function(_, id) { return "remove_button" }, 
        'name': function(_, name) { return "name_remove" +i }, 
        'value': 'Remove' 
       }).on("click", function(){ 
        var a = $(this).parent(); 
        var b= a.parent(); 
        i=i-1 
        $('#id_form-TOTAL_FORMS').val(i); 
        b.remove(); 

        $('.player-instances tr').each(function(index, value){ 
         $(this).find('.data_input').each(function(){ 
          $(this).attr({ 
           'id': function (_, id) { 
            var idData= id; 
            var splitV= String(idData).split('-'); 
            var fData= splitV[0]; 
            var tData= splitV[2]; 
            return fData+ "-" +index + "-" + tData 
           }, 
           'name': function (_, name) { 
            var nameData= name; 
            var splitV= String(nameData).split('-'); 
            var fData= splitV[0]; 
            var tData= splitV[2]; 
            return fData+ "-" +index + "-" + tData 
           } 
          }); 
         }) 
        }) 
       }) 
      } 
      else{ 
       $(this).attr({ 
        'id': function (_, id) { 
         var idData= id; 
         var splitV= String(idData).split('-'); 
         var fData= splitV[0]; 
         var tData= splitV[2]; 
         return fData+ "-" +i + "-" + tData 
        }, 
        'name': function (_, name) { 
         var nameData= name; 
         var splitV= String(nameData).split('-'); 
         var fData= splitV[0]; 
         var tData= splitV[2]; 
         return fData+ "-" +i + "-" + tData 
        } 
       }); 

      } 
     }).end().appendTo("tbody"); 
     $('#id_form-TOTAL_FORMS').val(1+i); 
     i++; 

    }); 
</script> 
</body> 
</html> 

========================== ===================

すべてのオブジェクトを保存することができません。それを修正してください。

+0

-pname。 – Ykh

+0

ok ..私はどこでスクリプトを変更する必要がありますか? –

+0

私の新しい答えを参照してください – Ykh

答えて

0

あなただけのアイテムの最初のものを保存することができた理由は、追加した行のIDと名前はまだid_form-0-pnameのがid_form-1-PNAMEをする(パターンがid_form-I-pnameにある)に変更されていないです。

django-dynamic-formset libに使用し、これを達成するための別の方法、コードはここにある:

news.html

<html> 
<head> 

    <title>gffdfdf</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
    <script src="/static/jquery.formset.js"></script> 
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 

</head> 
<body> 

<div class="container"> 

    <form id="myForm" action="" method="post" class=""> 
     {% csrf_token %} 
     <h2> Team</h2> 
     {% for field in form %} 
      {{ field.errors }} 
      {{ field.label_tag }} : {{ field }} 
     {% endfor %} 
     {{ form.player.management_form }} 

     <h3> Product Instance(s)</h3> 
     <table id="table-product" class="table"> 
      <thead> 
      <tr> 
       <th>player name</th> 
       <th>highest score</th> 
       <th>age</th> 
      </tr> 

      </thead> 
      {% for player in form.player %} 
       <tbody class="player-instances"> 

       <tr> 
        <td>{{ player.pname }}</td> 
        <td>{{ player.hscore }}</td> 
        <td>{{ player.age }}</td> 
       </tr> 

       </tbody> 
      {% endfor %} 
     </table> 
     <button type="submit" class="btn btn-primary">save</button> 

    </form> 
</div> 
<script> 
    $(function() { 
     $('#myForm tbody tr').formset(); 
    }) 
</script> 
</body> 
</html> 

それはenter image description here 、それは簡単な仕事だように見えています。 jquery.formset.jshereのgithubからダウンロードできます.Docはhereです。 あなたが好きなのconf jquery.formset.jsと追加\削除リンクのテキストとCSSを変更することができます。その理由は、追加した行のIDと名前はまだid_form-0-pnameのがid_form-1-pnameのされていないか、id_form-3である

/* Setup plugin defaults */ 
$.fn.formset.defaults = { 
    prefix: 'form',     // The form prefix for your django formset 
    formTemplate: null,    // The jQuery selection cloned to generate new form instances 
    addText: 'add another',   // Text for the add link 
    deleteText: 'remove',   // Text for the delete link 
    addCssClass: 'add-row',   // CSS class applied to the add link 
    deleteCssClass: 'delete-row', // CSS class applied to the delete link 
    formCssClass: 'dynamic-form', // CSS class applied to each form in a formset 
    extraClasses: [],    // Additional CSS classes, which will be applied to each form in turn 
    keepFieldValues: '',    // jQuery selector for fields whose values should be kept when the form is cloned 
    added: null,      // Function called each time a new form is added 
    removed: null     // Function called each time a form is deleted 
}; 
+0

ありがとうございます..私は上記のコードを試しました...しかし今回は "ValidationError at/post-new/ ['ManagementFormデータがありませんか']で改ざんされました –

+0

' form.player.management_form' not form .players.management_form'、プレイヤーの後ろには何もありません – Ykh

+0

ありがとうございました! –

0

form.player_instancesをループする必要があります。

if request.POST: 
    form = TeamForm(request.POST) 
    form.player_instances = PlayerFormset(request.POST) 
    if form.is_valid(): 
    team= Team() 
    team.tname= form.cleaned_data['tname'] 
    team.save() 

    if form.player_instances.is_valid(): 

     for item in form.player_instances: 
      player = Player() 
      player.pname= item.cleaned_data['pname'] 
      player.hscore= item.cleaned_data['hscore'] 
      player.age= item.cleaned_data['age'] 
      player.save() 
      team.player.add(player) 
      team.save() 
+0

最後のオブジェクトだけを保存しようとしたが...あなたの応答#ankita gupta –

+0

のためにお返事いただきありがとうございます。ループ内のチームオブジェクトを保存する必要があります。 –

+0

同じことが再び起こっています....最後のオブジェクトだけが保存されています。 –

関連する問題