我正在用现有对象的查询集创建一个表格.表中的几个字段应更改,其他字段应显示但不更改.为了显示不可编辑的字段,我在表单中使用了"disabled"小部件.GET请求做的一切都是正确的.但是POST请求并不保存对解析字段的更改,因为未解析字段是必需的,并且已被禁用并阻止发送现有值. 我try 使用jQuery从example,但它不工作.此外,我不明白如何在形式集中引用不同的id.

型号:

class Order(models.Model):
    car = models.ForeignKey(
        Car,
        blank=True,
        null=True,
        on_delete=models.PROTECT,
        related_name='car_orders',
    )
    department = models.ForeignKey(
        Department,
        blank=False,
        null=False,
        on_delete=models.PROTECT,
        related_name='dep_orders',
    )
    ...

def orders_list(request, year, month, day):
    orders = Order.objects.filter(
        order_date__year=year, order_date__month=month, order_date__day=day
    )

    if request.method == 'POST':
        formset = OrderClose表格Set(
            request.POST or None, queryset=orders, prefix='order'
        )
        if formset.is_valid():
            formset.save(commit=False)
            for form in formset:
                form.save()

    formset = OrderClose表格Set(queryset=orders, prefix='order')

    context = {'orders': orders, 'formset': formset}

    return render(request, 'orders/orders_list.html', context)

表格

class OrderClose表格(forms.Model表格):
    class Meta:
        model = Order
        fields = ( 
            'type_car',
            'department',
            ...
        )
        widgets = {
            'car': forms.Select(attrs={'style': 'width: 100%'}),
            'department': forms.Select(attrs={'disabled': 'True', 'style': 'width: 100%'}),
            ...
        }

模板

<form method="post" action="{% url 'orders:orders_list' year month day %}">
        {% csrf_token %}

        {{ formset.management_form }}
        {{ formset.non_form_errors.as_ul }}
        <table class="table table-order" id="order-formset">

          {% for form in formset %}
            {% if forloop.first %}
              <thead>
                <tr>
                  {% for field in form.visible_fields %}
                    <th>{{ field.label|capfirst }}</th>
                  {% endfor %}
                </tr>
              </thead>
            {% endif %}

            <tbody>
              <tr>
               {% for field in form %}
                  <td>
                  {% if field == car %}
                    {% for hidden in form.hidden_fields %}
                     {{ hidden }}
                    {% endfor %}
                  {%  endif %}

                  {% if field == form.route_movement %}
                    <a href="{% url 'orders:order_detail' form.id.value %}">
                      {{ field|addclass:'input-box input-select' }}
                    </a>
                  {% else %}
                    {{ field|addclass:'input-box input-select' }}
                  {% endif %}
                  </td>
                 {% endfor %}
              </tr>
            </tbody>

          {% endfor %}
        </table>
  ...
</form>

<script>
  $('id_order-0-department').submit(function(e) {
    $(':disabled').each(function(e) {
        $(this).removeAttr('disabled');
    })
  });
</script>

作为响应,使用NEXT ID获取表单集中的表单ID:

<select name="order-0-department" disabled="True" id="id_order-0-department"></select>

那么,如何创建一个包含可编辑字段的表,但保持字段中的数据不变呢?

推荐答案

设置disabled只会使字段不可编辑,所以人们仍然可以伪造一个POST请求来改变字段.

您应该将该字段设置为.disabled = True,这不仅会跳过这些字段,还会防止用户伪造会以某种方式更改这些字段的POST请求,例如:

class OrderCloseForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['department'].disabled = True

    class Meta:
        model = Order
        fields = (
            'type_car',
            'department',
            # …
        )
        widgets = {
            'car': forms.Select(attrs={'style': 'width: 100%'}),
            'department': forms.Select(attrs={'style': 'width: 100%'}),
            # …
        }

该视图实际上比目前的视图简单得多:您可以直接保存FormSet:

def orders_list(request, year, month, day):
    orders = Order.objects.filter(
        order_date__year=year, order_date__month=month, order_date__day=day
    )

    if request.method == 'POST':
        formset = OrderCloseFormSet(
            request.POST, request.FILES, queryset=orders, prefix='order'
        )
        if formset.is_valid():
            formset.save()  # commit=True
            return redirect('name-of-some-view')

    else:
        formset = OrderCloseFormSet(queryset=orders, prefix='order')

    context = {'orders': orders, 'formset': formset}
    return render(request, 'orders/orders_list.html', context)

Note:如果POST请求成功,您应该设置为redirect [Django-doc] 落实Post/Redirect/Get pattern [wiki]条. 这样可以避免在用户刷新 浏览器.

Javascript相关问答推荐

为什么getRecord()会因为与_logger相关的错误而失败?(使用Hedera SDK)

根据总价格对航班优惠数组进行排序并检索前五个结果- Angular HTTP请求

仅圆角的甜甜圈图表

深嵌套的ng-container元素仍然可以在Angular 布局组件中正确渲染内容吗?

在页面上滚动 timeshift 动垂直滚动条

传递一个大对象以在Express布局中呈现

配置WebAssembly/Emscripten本地生成问题

空的结果抓取网站与Fetch和Cheerio

使用js构造一个html<;ath&>元素并不能使其正确呈现

如何将未排序的元素追加到数组的末尾?

使用getBorbingClientRect()更改绝对元素位置

MongoDB受困于太多的数据

Google脚本数组映射函数横向输出

如何使用Astro优化大图像?

为列表中的项目设置动画

React:防止useContext重新渲染整个应用程序或在组件之间共享数据而不重新渲染所有组件

计算对象数组中属性的滚动增量

有角粘桌盒阴影

使用Java脚本替换字符串中的小文本格式hashtag

JSX/React -如何在组件props 中循环遍历数组