2017-12-11 5 views
-1

폼 및 뷰를 사용하여 formset 추가 필드 데이터를 저장하려고합니다. 예 : - 팀에는 선수가 없습니다. 그래서 나는 더 많은 버튼을 추가하려면 클릭하여 새 플레이어를 추가하고 싶습니다. 코드는 아래에서 시도했습니다. 내가 한 번에 두 개 이상의 플레이어를 추가하면 문제는 단지 o/p for below code폼 및 뷰를 사용하여 django 동적 formset 데이터를 저장하는 방법

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() 

전망 마지막 개체 값을 저장입니다 ... 평

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

: 당신은 같은 conf의 jquery.formset.js로 추가 \ 삭제 링크의 텍스트와 CSS를 변경할 수 있습니다 -pname. – Ykh

+0

좋아 .. 내가 어디 스크립트에서 변경해야합니까 ?? –

+0

내 새로운 대답을 참조 – Ykh

답변

0

만 항목 중 첫 번째는 당신이 머무르는 라인 ID와 이름을 저장할 수있는 이유는 아직 (패턴이 id_form-I-PNAME입니다) id_form-0-PNAME-1-PNAME을 id_form로 변경되지 않습니다.

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입니다. 그 이유는 당신이 머무르는 라인 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'이 아닌 '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

같은 일이 또 일어나고 있습니다 .... 마지막 물건 만 저축 중입니다. –