You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何基于CreateView表单选择过滤ListView列表?

解决方案

问题A:客户过滤报错修复

报错核心原因是customer_id为数值类型,而includes()是字符串专属方法,直接调用会触发类型错误。同时当前过滤逻辑完全错误——应该用选中的客户ID匹配Program的customer_id,而非用Program名称匹配选中值;此外下拉框应监听change事件(选值触发)而非click事件(点击就触发)。

问题B:显示客户名称而非ID

当前序列化数据仅包含customer_id,缺少客户名称字段。需要在视图层关联查询出CustomerName的company属性,前端直接调用该字段即可,且完全不影响基于customer_id的过滤逻辑。


修改后的完整代码

1. 视图代码(更新序列化逻辑)

import json
from django.urls import reverse_lazy
from django.views.generic import CreateView, ListView
from .models import ProgramName

class ProgramAddView(CreateView, ListView):
    template_name = 'app/ProgramAdd.html'
    form_class = Programform
    model = ProgramName
    success_url = reverse_lazy('Part Number Add')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 关联查询获取客户名称,只序列化需要的字段
        program_data = ProgramName.objects.values('id', 'program', 'customer_id', 'customer__company')
        context["qs_json"] = json.dumps(list(program_data))
        return context

2. HTML及JS代码(修正模板结构、过滤逻辑、显示内容)

{% extends 'base.html' %}

{% block content %}
  <h2>Program</h2>
  <form method="post" class='formarea'>
    <div id='formarea' class='formdiv'>
      {{ form.media.js }}
      <table>
        {{ form.as_table }}
      </table>
      {% csrf_token %}
      <button type="submit">Save</button>
      <a href="{% url 'HomePage' %}">Nevermind</a>
    </div>
  </form>

  <h2>Program List</h2>
  <table class="table table-hover">
    <thead>
      <tr>
        <th scope="col">Program</th>
        <th scope="col">Customer</th>
      </tr>
    </thead>
    <tbody id="program-table-body">
      <!-- 初始渲染所有数据 -->
      {% for item in object_list %}
      <tr>
        <td>{{ item.program }}</td>
        <td>{{ item.customer.company }}</td>
      </tr>
      {% empty %}
      <tr>
        <td colspan="2">No objects yet.</td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
{% endblock %}

{% block scripts %}
<script>
    // 用safe过滤器避免Django自动转义引号,无需手动替换&
    const rdata = JSON.parse('{{ qs_json|safe }}');
    const customerSelect = document.getElementById('id_customer');
    const tableBody = document.getElementById('program-table-body');

    // 监听下拉框选值事件
    customerSelect.addEventListener('change', () => {
        const selectedCustomerId = parseInt(customerSelect.value);
        tableBody.innerHTML = "";

        // 过滤逻辑:匹配数值类型的customer_id,未选则显示全部
        const filteredArr = selectedCustomerId 
            ? rdata.filter(program => program.customer_id === selectedCustomerId)
            : rdata;

        if (filteredArr.length > 0) {
            filteredArr.forEach(program => {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td><b>${program.program}</b></td>
                    <td><b>${program.customer__company}</b></td>
                `;
                tableBody.appendChild(row);
            });
        } else {
            tableBody.innerHTML = '<tr><td colspan="2"><b>No results found...</b></td></tr>';
        }
    });
</script>
{% endblock scripts %}

额外优化说明

  • 模板中使用{{ qs_json|safe }}替代手动转义,更安全简洁
  • 将列表改为表格结构,贴合业务展示逻辑
  • 增加“未选择客户时显示全部数据”的逻辑
  • 用forEach替代map(仅渲染无需返回数组),性能更优

内容的提问来源于stack exchange,提问作者ItchyPancake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 13:05:30