首页 > 解决方案 > 在动态表单django中添加多个项目

问题描述

我是 Web 编程的新手,我正在尝试创建一种可以聚合许多 IP 地址和端口的表单,当我单击只有一个 IP 和端口的峰会时,它可以工作并且我的模型已更新,但是当我尝试添加多个它不起作用。我意识到索引没有更新,但我不知道如何修复它

在此处输入图像描述:

1

#查看次数

from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.forms import modelformset_factory
from BrainCH.forms import formulario_crear_serv,formulario_members
from django.contrib import messages
from django.db import transaction,IntegrityError
from F5APP.models import CrearServicio,members

def Home(request):
    diccionario_home = {}
    return render(request,"home.html",diccionario_home)
    #return HttpResponse("Home")

def NuevoServicio(request):
    diccionario_crearservicio={}
    Membersformset=modelformset_factory(members, form=formulario_members)
    form =formulario_crear_serv(request.POST or None)
    formset=Membersformset(request.POST or None, queryset=members.objects.none(), prefix="members")
    if request.method== "POST":
        if form.is_valid() and formset.is_valid():
            try:
                with transaction.atomic():
                    crearServicio = form.save(commit=False)
                    crearServicio.save()
                    
                    
                    for member in formset:
                        data=member.save(commit=False)
                        data.crearServicio = crearServicio
                        data.save()
                        #print("paso 7")
            except IntegrityError:
                print("Error")
            return redirect("list")
    diccionario_crearservicio["formset"] = formset
    diccionario_crearservicio["form"] = form
    return render(request,"CrearServicio.html",diccionario_crearservicio)

def list(request):
    datas= CrearServicio.objects.all()
    return render(request,"list.html",{"datas":datas})

#楷模

from django.db import models



class persistencias(models.Model):
    tipo=models.CharField(max_length=15)

    def __str__(self):
        return(self.tipo)

class serviciosite(models.Model):           #act-act o act-bkp
    tipo=models.CharField(max_length=15)

    def __str__(self):
        return(self.tipo)

class areas(models.Model):
    tipo=models.CharField(max_length=30)

    def __str__(self):
        return(self.tipo)

class ambientes(models.Model):
    tipo=models.CharField(max_length=15)

    def __str__(self):
        return(self.tipo)

class estadositecdlv(models.Model):
    tipo=models.CharField(max_length=10)

    def __str__(self):
        return(self.tipo)

class estadositelgvl(models.Model):
    tipo=models.CharField(max_length=10)

    def __str__(self):
        return(self.tipo)

class algoritmo_local(models.Model):
    tipo=models.CharField(max_length=20)

    def __str__(self):
        return(self.tipo)


class CrearServicio(models.Model):      #capacidad de ser una tabla y hacer CRUD
    cliente=models.CharField(max_length=30)
    correo=models.EmailField()
    ambiente=models.ForeignKey(ambientes,on_delete=models.CASCADE)
    area=models.ForeignKey(areas,on_delete=models.CASCADE)
    nombre_servicio=models.CharField(max_length=30)
    ip_servicio=models.GenericIPAddressField()
    pto_servicio=models.CharField(max_length=5)
    persistencia=models.ForeignKey(persistencias,on_delete=models.CASCADE)
    modalidad=models.ForeignKey(serviciosite,on_delete=models.CASCADE)
    algoritmo_balanceo=models.ForeignKey(algoritmo_local,on_delete=models.CASCADE)

    def __str__(self):
        return(self.nombre_servicio)


class members(models.Model):
    crearServicio=models.ForeignKey(CrearServicio,on_delete=models.CASCADE)
    nodo=models.GenericIPAddressField()
    port=models.CharField(max_length=5)

    def __str__(self):
        return(self.crearServicio)

#形式

from django import forms
from django.forms import ModelForm
from F5APP.models import CrearServicio, members

class formulario_crear_serv(ModelForm):       
    class Meta:
        model=CrearServicio
        fields= ["cliente",
                 "correo",
                 "ambiente",
                 "area",
                 "nombre_servicio",
                 "ip_servicio",
                 "pto_servicio",
                 "persistencia",
                 "modalidad",
                 "algoritmo_balanceo",]

class formulario_members(ModelForm):       
    class Meta:
        model=members
        fields= ["nodo",
                 "port",]
        widget = {
            "nodo":forms.TextInput(attrs={"class":"F5APP-field"}),
            "port":forms.TextInput(attrs={"class":"F5APP-field"}),
        }

#模板(CrearServicio.html)

{% extends 'base.html' %}
{% load static %}

{% block content %}
    <h1 style="padding-left: 30px;" >    Nuevo Servicio balanceado
    <i class="fas fa-hand-spock"></i>
    </h1>

    <!-- Divider -->
    <hr class="sidebar-divider my-0">

    <form method="POST">
        {% csrf_token %}
        {{ form.as_p}}
        
        <table class="table form-table table-bordered table-sm">
                            <thead class="text-center">
                            <tr>
                                <th>nodo</th>
                                <th>port</th>
                                <th></th>
                            </tr>
                            </thead>
                            <tbody>
                            {% for form_data in formset %}
                                <tr class="item">
                                    <td>
                                        {{ form_data.nodo }}
                                    </td>
                                    <td>
                                        {{ form_data.port }}
                                    </td>
                                    <td>
                                        <button type="button" class="btn btn-danger btn-sm remove-form-row"
                                                id="{{ formset.prefix }}">
                                          
                                            Delete
                                        </button>
                                    </td>
                                </tr>
                            {% endfor %}
                            <tr>
                                <td colspan="9"
                                    style="border-left: none!important; border-right: none !important; border-bottom: none!important;">
                                    <button type="button" class="btn btn-sm btn-success add-form-row"
                                            id="{{ formset.prefix }}">
                                       Add
                                    </button>
                                </td>
                            </tr>
                            </tbody>
                        </table>
                        {{ formset.management_form }}

        <button type="submit">Submit</button>
    </form>
{% endblock %}
{% block extra_script %}
    <script type="text/javascript" src="{% static 'Newjs/formset.js' %}"></script>
{% endblock %}

#模板(CrearServicio.html)

{% extends 'base.html' %}
{% load static %}

{% block content %}
    <table>
     <thead>
         <th>
             Servicio balanceado solicitado
         </th>
         <th>clienter</th>
         <th>correo</th>
         <th>ambiente</th>
         <th>area</th>
         <th>nombre_servicio</th>
         <th>ip_servicio</th>
         <th>pto_servicio</th>
         <th>persistencia</th>
         <th>modalidad</th>
         <th>algoritmo_balanceo</th>

     </thead>   
     <tbody>
         {% for data in datas %}
           <tr>
            <td>{{ data.cliente}}</td>
            <td>{{ data.correo }}</td>
            <td> {{ data.ambiente }}</td>
            <td> {{ data.area }}</td>
            <td> {{ data.nombre_servicio }}</td>
            <td> {{ data.ip_servicio }}</td>
            <td> {{ data.pto_servicio }}</td>
            <td> {{ data.persistencia }}</td>
            <td> {{ data.modalidad }}</td>
            <td> {{ data.algoritmo_balanceo }}</td>
           </tr>
         {% endfor %}
     </tbody>
    </table>
    
{% endblock %}

#JS Formset.js

function updateElementIndex(el, prefix, ndx) {
    var id_regex = new RegExp('(' + prefix + '-\\d+-)');
    var replacement = prefix + '-' + ndx + '-';
    if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex,
    replacement));
    if (el.id) el.id = el.id.replace(id_regex, replacement);
    if (el.name) el.name = el.name.replace(id_regex, replacement);
}

function addForm(btn, prefix) {
    var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
    if (formCount < 1000) {
        // Clone a form (without event handlers) from the first form
        var row = $(".item:last").clone(false).get(0);

        // Insert it after the last form
        $(row).removeAttr('id').hide().insertAfter(".item:last").slideDown(300);

        // Remove the bits we don't want in the new row/form
        // e.g. error messages
        $(".errorlist", row).remove();
        $(row).children().removeClass("error");

        // Relabel or rename all the relevant bits
        $(row).find('.formset-field').each(function () {
            updateElementIndex(this, prefix, formCount);
            $(this).val('');
            $(this).removeAttr('value');
            $(this).prop('checked', false);
        });

        // Add an event handler for the delete item/form link
        $(row).find(".delete").click(function () {
            return deleteForm(this, prefix);
        });
        // Update the total form count
        $("#id_" + prefix + "-TOTAL_FORMS").val(formCount + 1);

    } // End if

    return false;
}


function deleteForm(btn, prefix) {
      var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
      if (formCount > 1) {
          // Delete the item/form
          var goto_id = $(btn).find('input').val();
          if( goto_id ){
            $.ajax({
                url: "/" + window.location.pathname.split("/")[1] + "/formset-data-delete/"+ goto_id +"/?next="+ window.location.pathname,
                error: function () {
                  console.log("error");
                },
                success: function (data) {
                  $(btn).parents('.item').remove();                 
                },
                type: 'GET'
            });
          }else{
            $(btn).parents('.item').remove();
          }

          var forms = $('.item'); // Get all the forms
          // Update the total number of forms (1 less than before)
          $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
          var i = 0;
          // Go through the forms and set their indices, names and IDs
          for (formCount = forms.length; i < formCount; i++) {
              $(forms.get(i)).find('.formset-field').each(function () {
                  updateElementIndex(this, prefix, i);
              });
          }
      } // End if

      return false;
  }

  $("body").on('click', '.remove-form-row',function () {
    deleteForm($(this), String($('.add-form-row').attr('id')));
  });

  $("body").on('click', '.add-form-row',function () {
      return addForm($(this), String($(this).attr('id')));
  });

标签: pythondjangodjango-modelsdjango-forms

解决方案


在 Forms 中,是“widgets”而不是“widget”,这就是“class”:“formset-field”没有生效的原因。


推荐阅读