3

多个 DEVICE 表单可以在一个页面(订单)上显示为选项卡。当用户关闭选项卡并点击save,然后租用该特定订单 (ID) 时,用户仍会看到他已删除的选项卡。作为一种快速的解决方法,在 html 代码中内置了一个复选框,但这不是我们所希望的。

目前我的代码view.py看起来像这样。

def edit_order(request,id = None, order_id = None):
    order = Order.objects.get(id=id)
    '''some stuff'''
    if request.method == 'POST': 
            formCustomer = CustomerModelForm(request.POST,instance=Customer.objects.get(order=order.id))
            formInfo = InfoModelForm(request.POST,instance=Info.objects.get(order=order.id))
            DBFormSet = modelformset_factory(DB, extra=1, can_delete=True, form=LUNModelForm)
            formset = DBFormSet(request.POST or None, queryset=DB)  
            if formset.is_valid():
                            for i,frm in enumerate(formset.forms):
            if frm.cleaned_data['id']: 
                if frm.is_valid():
                    if not frm.cleaned_data['capacityGB'] > 0:
                        frm.cleaned_data['id'].delete()
                    elif frm.cleaned_data['DELETE'] == True: 
                        frm.cleaned_data['id'].delete()
                        #frm.save() or formset.save() ??
                    else:
                        dev = frm.cleaned_data['id']
                        dev.capacity = frm.cleaned_data['capacity']
                        dev.save()

我怀疑标签没有保持关闭的问题是“ can_delete”的问题,但是当我添加它时似乎没有什么不同。然后我读到这个问题可能与formset.save,这也没有解决任何问题。下面的html代码:

html:

                <ul class="nav nav-tabs" id="tab4Headers">

{% for form in formsetDEVICE.forms %}
  {% if forloop.first %}
    {% if form.errors %}
                <li class="active"><a href="#tab4_{{forloop.counter}}" data-toggle="tab">DEVICE <i class="icon-warning-sign"></i> </a></li> <!-- section 4.1 -->
    {% else %}
                <li class="active"><a href="#tab4_{{forloop.counter}}" data-toggle="tab">DEVICE</a></li> <!-- section 4.1 -->
    {% endif %}

  {% else %}
    {% if form.errors %}
                <li><a href="#tab4_{{forloop.counter}}" data-toggle="tab"><button class="close" type="button" id="close-tab4_{{forloop.counter}}">×</button>DEVICE <i class="icon-warning-sign"></i> </a></i></li> <!-- section 4.2 ... 4.n -->
                <!--{% if formsetDEVICE.can_delete %}
                  <li>{{ form.DELETE }}</li>
                {% endif %}-->
    {% else %}
                <li><a href="#tab4_{{forloop.counter}}" data-toggle="tab"><button class="close" type="button" id="close-tab4_{{forloop.counter}}">×</button>DEVICE</a></li> <!-- section 4.2 ... 4.n -->
                <!--{% if formsetDEVICE.can_delete %}
                  <li>{{ form.DELETE }}</li>
                {% endif %}-->
    {% endif %}
  {% endif %}
{% endfor %}
                </ul>

由于尚不清楚如何通过关闭选项卡(然后单击save按钮)来删除选项卡,因此当前的解决方法只是在选项卡上插入一个包含复选框的部分,如下所示:

  {# --- delete item --- #}
  {% if form.instance.pk %}
  {# render row for DELETE-flag only for forms with existing instance #}
  <tr>
  <td colspan="2">
  </td>
  <td colspan="2">
    edit Action required: <br/><br/>
    {{form.DELETE|safe}} delete this DEVICE from the Order.
  </td>
  </tr>
  {% endif %}
  {# --- END delete item --- #}

当前的解决方法有效,但这不是所需的功能。我已经尝试了这里看到的一些建议,但无济于事。我认为这个问题更多地与 html 和 view.py 之间的链接有关(所以frm.cleaned_data['DELETE']尽管我可能错了。

编辑:

我怀疑要解决这个问题,需要插入 js 代码和/或 css。

4

1 回答 1

1

我对inlineformset_factory有同样的问题。阅读基本的 Django 类,我发现问题似乎出在BaseFormSet类(或类似的类)中,该_should_delete_form()方法在cleaned_data 中查找表单DELETE值,但使用调试我发现delete值在cleaned_data 中不存在,在填充cleaned_data 时, DELETE字段都不存在。

我认为这可能是因为 DELETE 字段是由 FormSet 类动态创建的,但是在创建 DELETE 字段之前(在表单初始化的某个地方?可能),clean_data 由 Form 类填充,因此该字段不存在,clean_data DELETE 值未填充。

在基本 FormSet 类的某处,动态创建的 DELETE 字段值必须包含在 clean_data 中,我找到了一个快速且临时的解决方案,将 DELETE 字段添加到表单类:

class RutinaForm(ModelForm):
    DELETE = forms.BooleanField(required=False, widget=forms.CheckboxInput())

    class Meta:
        model = Rutina
        fields = '__all__'
        exclude = ('usuario',)
        widgets = { .........}

这样,DELETE 字段就存在,因此它的值被清理并添加到cleaned_data。
这可以看作是一个“machetazo”,但它有效!至少是暂时的。我将继续阅读基本代码并查看它是否是一个错误,或者发生了什么。

注意:对不起我的英语,我不是专家,所以请给我你的意见。

如果您需要,或者您可以找到问题所在,这是我的观点:

rutinaFormSet = inlineformset_factory(Usuario, Rutina, form=RutinaForm, can_delete=True, extra=1)
if request.method == 'POST':
    formSet = rutinaFormSet(request.POST, instance=usuario)
    if formSet.is_valid():

        formSet.save()

else:
    formSet = rutinaFormSet(instance=usuario)
于 2018-06-12T06:15:03.783 回答