Django Formset 删除字段不显示

Django Formset Delete Field Not Showing

我需要在我的模板中手动呈现我的表单集,并且当我手动呈现时我无法将删除复选框字段放入模板中。但是,它确实在我渲染 {{form.as_table}}.

时显示

views.py

QuoteManifestForm= modelformset_factory(QuoteManifest, QManifestForm, can_delete = True)

模板 - 这不显示 {{form.DELETE}} 但其他所有字段都显示正常,包括我可以在 DOM 中看到的 id。

{{ manifest.management_form }} <--!I passed QuoteManifestForm to template as 'manifest'-->

          {% for form in manifest.forms %}
            <div id="form_set">
                <table id = 'manifest-table25' class="manifest-table2" width=100%>
                  {% csrf_token %}
                  <tbody width=100%>
                    <tr class="manifest-row">
                      <td width = 17.5% class="productCode" onchange="populateProduct(this)">{{form.ProductCode}}</td>
                      <td width = 32.5% class="description">{{form.DescriptionOfGoods}}</td>
                      <td width = 12.5% class="quantity" oninput="calculateUnit(this)">{{form.UnitQty}}</td>
                      <td width = 12.5% class="unitType">{{form.Type}}</td>
                      <td width = 12.5% class="price" oninput="calculate(this)">{{form.Price}}</td>
                      <td width = 12.5% class="amount2">{{form.Amount}}</td>
                      <td>{{form.DELETE}}</td>
                      {{form.id}}
                    </tr>
                  </tbody>
                </table>
            </div>
            {% endfor %}

知道为什么这不起作用吗?

更新:

我在 django 文档中发现,如果您手动渲染,您应该在表单中包含如下内容。我试过了,但我的模板中仍然没有删除字段:

{% if form2.can_delete %}
  <td> {{form.DELETE}}</td>
{% endif %}

要重现的代码

views.py

def QuoteView(request):
    QuoteManifestForm= modelformset_factory(QuoteManifest, fields =('ProductCode', 'DescriptionOfGoods', 'UnitQty', 'Type','Amount', 'Price'), can_delete = True)
    if request.method == "POST":
       form2 = QuoteManifestForm(request.POST)
       form2.save()

       return redirect('HomeView')

    else:
       form2 = QuoteManifestForm()
        context = {

            'form2': form2,

        }
        return render(request, 'quote.html', context)

quote.html

{{ form2.management_form }}
            <div id="form_set">
              {% for form2 in form2.forms %}
                <table id = 'manifest-table25' class="manifest-table2" width=100%>
                  {% csrf_token %}
                  <tbody width=100%>
                    <tr class="manifest-row">
                      <td width = 17.5% class="productCode" onchange="populateProduct(this)">{{form2.ProductCode}}</td>
                      <td width = 32.5% class="description">{{form2.DescriptionOfGoods}}</td>
                      <td width = 12.5% class="quantity" oninput="calculateUnit(this)">{{form2.UnitQty}}</td>
                      <td width = 12.5% class="unitType">{{form2.Type}}</td>
                      <td width = 10.5% class="price" oninput="calculate(this)">{{form2.Price}}</td>
                      <td width = 12.5% class="amount2">{{form2.Amount}}</td>
                      <td>{{form2.DELETE}}</td>
                      {{form2.id}}
                    </tr>
                  </tbody>
                </table>
              {% endfor %}
            </div>

models.py

class QuoteManifest(models.Model):
    ProductCode = models.ForeignKey(Product, null=True, blank=True)
    DescriptionOfGoods = models.CharField(max_length=500, blank=True)
    UnitQty = models.CharField(max_length=10, blank=True)
    Type = models.CharField(max_length=50, blank=True)
    Amount = models.CharField(max_length=100, blank=True)
    Price = models.CharField(max_length=100, blank=True)

{{form2.DELETE}} 应该呈现一个复选框。这是我无法工作的。当我将表单呈现为 {{form2.as_p}} 时它确实有效,但在我的情况下这对我不起作用。

基于此处的示例:https://docs.djangoproject.com/en/3.0/topics/forms/formsets/#manually-rendered-can-delete-and-can-order

看起来你的观点是:

def QuoteView(request):
    QuoteManifestFormset= modelformset_factory(QuoteManifest, fields =('ProductCode', 'DescriptionOfGoods', 'UnitQty', 'Type','Amount', 'Price'), can_delete = True)   # Renamed as formset for clarity
    if request.method == "POST":
       formset = QuoteManifestFormset(request.POST) # also renamed
       formset.save()
       return redirect('HomeView')
    else:
       formset = QuoteManifestFormset()
        context = {'formset': formset}
        return render(request, 'quote.html', context)

而你的 quote.html 我认为 {% for form2 in form2.forms %} 需要 {% for form in formset %}

<form method="post">
    {{ formset.management_form }}
    {% for form in formset %}  
      <table id = 'manifest-table25' class="manifest-table2" width=100%>
        {% csrf_token %}
        <tbody width=100%>
          <tr class="manifest-row">
            <td width = 17.5% class="productCode" onchange="populateProduct(this)">{{form.ProductCode}}</td>
            <td width = 32.5% class="description">{{form.DescriptionOfGoods}}</td>
            <td width = 12.5% class="quantity" oninput="calculateUnit(this)">{{form.UnitQty}}</td>
            <td width = 12.5% class="unitType">{{form.Type}}</td>
            <td width = 10.5% class="price" oninput="calculate(this)">{{form.Price}}</td>
            <td width = 12.5% class="amount2">{{form.Amount}}</td>
            <td>{{form.DELETE}}</td>
            {{form.id}}
          </tr>
        </tbody>
      </table>
    {% endfor %}
</form>

使用您的示例代码,我能够创建一个似乎使用 {{ form.DELETE }} 语法呈现复选框的示例。

看来我的示例代码与您已有的非常相似。我确实向 QuoteManifest 模型中的 ProductCode 变量添加了一个 on_delete 参数。而且我不确定您的 Product 模型是什么样的,所以我只是创建了一个虚拟模型。我还删除了您的 CSS 类 和 JavaScript 电话。是否有可能您 JavaScript 中的某些内容覆盖了复选框?

正如您将在我的示例中看到的那样,我确实得到了复选框。我的代码在下面,here is a link to the working demo on repl.it.

models.py

from django.db import models

class Product(models.Model):
    ProductName = models.CharField(max_length=100, unique=True)


class QuoteManifest(models.Model):
    ProductCode = models.ForeignKey(Product, null=True, blank=True, on_delete=models.CASCADE)
    DescriptionOfGoods = models.CharField(max_length=500, blank=True)
    UnitQty = models.CharField(max_length=10, blank=True)
    Type = models.CharField(max_length=50, blank=True)
    Amount = models.CharField(max_length=100, blank=True)
    Price = models.CharField(max_length=100, blank=True)

views.py

from django.shortcuts import render, redirect
from django.forms.models import modelformset_factory
from .models import QuoteManifest

def QuoteView(request):
  QuoteManifestForm= modelformset_factory(QuoteManifest, fields =('ProductCode', 'DescriptionOfGoods', 'UnitQty', 'Type','Amount', 'Price'), can_delete=True)

  form2 = QuoteManifestForm()
  context = {
  'form2': form2,
  }
  return render(request, 'quote.html', context)

templates/quote.html

<div id="form_set">
{% for form2 in form2.forms %}
  <table id="manifest-table25" width=100%>
    {% csrf_token %}
    <tbody width=100%>
      <tr>
        <td>{{form2.ProductCode}}</td>
        <td>{{form2.DescriptionOfGoods}}</td>
        <td>{{form2.UnitQty}}</td>
        <td>{{form2.Type}}</td>
        <td>{{form2.Price}}</td>
        <td>{{form2.Amount}}</td>
        <td>{{form2.DELETE}}</td>
      </tr>
    </tbody>
  </table>
{% endfor %}
</div>