簡體   English   中英

如何使用表單和視圖保存 django 動態表單集數據

[英]How can i save django dynamic formset data using forms and views

我正在嘗試使用表單和視圖保存表單集額外字段數據。 例如:-團隊沒有玩家。 所以我想通過點擊添加更多按鈕來添加新玩家。我在下面嘗試的代碼。 問題是如果我一次添加一個以上的玩家......它只為下面的代碼保存最后一個對象值的o/p

模型.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

表格.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>

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

我無法保存所有對象。 請更正

您需要遍歷 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()

您只能保存第一個項目的原因是您添加的行 id 和名稱仍然是 id_form-0-pname 不會更改為 id_form-1-pname(模式是 id_form-i-pname)。

實現此目的的另一種方法,使用 lib django-dynamic-formset ,代碼在這里:

新聞.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>

它看起來像在此處輸入圖片說明 它簡單而有效。 jquery.formset.js可以從這里的github 下載。Doc is here 您可以使用 conf jquery.formset.js更改添加\\刪除鏈接的文本和 css,例如:

/* 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
};

**對您的 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> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.formset/1.2.2/jquery.formset.js"></script> </head> <body> <div class="container"> <form method="post" class=""> {% csrf_token %} <h2> Team</h2> {% for field in form %} {{ field.errors }} {{ field.label_tag }} : {{ field }} {% endfor %} {{ form.players.management_form }} <div style="display: none" > {{ form.players.empty_form }}</div> <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" id="playerFrmTableId"> <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> $("#input_add").click(function() { let formCount = parseInt($('#id_form-TOTAL_FORMS').val()); var html = `<tr> <td>{{ form.players.empty_form.pname }}</td> <td>{{ form.players.empty_form.hscore }}</td> <td>{{ form.players.empty_form.age }}</td> <td> <input id="input_add" type="button" name="add" value=" Add More " class="tr_clone_add btn data_input"> </td> </tr>`; html = html.replace(/__prefix__/g, formCount); $('#id_form-TOTAL_FORMS').val(formCount + 1); $('#playerFrmTableId').append(html); }); </script> </body> </html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM