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

如何在Django CreateView中实现下拉菜单搜索/筛选功能

实现Django下拉菜单的搜索筛选功能

嘿,针对你这个拥有上千条选项的下拉菜单添加搜索筛选的需求,完全可以通过Django第三方应用或者Bootstrap来实现,下面给你具体的落地方案:

一、使用Django第三方应用:django-autocomplete-light

这是Django生态里专门处理自动补全/下拉筛选的成熟库,非常适合大量选项的场景,后端处理筛选逻辑,体验流畅。

步骤1:安装依赖

pip install django-autocomplete-light

然后把dal和dal_select2添加到你的settings.py的INSTALLED_APPS里(注意要放在django.contrib.admin前面):

INSTALLED_APPS = [
    'dal',
    'dal_select2',
    'django.contrib.admin',
    # ... 其他已有的app
]

步骤2:修改forms.py

把原来的CharField替换为自动补全字段,同时配置数据源:

from django import forms
from .models import Model_Model01
from dal import autocomplete

class Form_Model01(forms.ModelForm):
    item_01 = forms.ModelChoiceField(
        queryset=Model_Model01.objects.all(),
        widget=autocomplete.ModelSelect2(url='item-autocomplete'),
        required=False
    )

    class Meta:
        model = Model_Model01
        fields = ["item_01"]

步骤3:添加URL配置

在你的urls.py里注册自动补全的视图:

from django.urls import path
from dal import autocomplete
from .models import Model_Model01

urlpatterns = [
    # ... 其他已有URL
    path('item-autocomplete/', autocomplete.Select2QuerySetView.as_view(model=Model_Model01), name='item-autocomplete'),
]

步骤4:更新模板

不需要大改,原来的模板代码可以直接用,因为dal会自动渲染带搜索框的下拉组件:

<form method="POST" action="" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.item_01 }}
    <input type="submit" value="Submit">
</form>

二、使用Bootstrap结合JavaScript实现纯前端筛选

如果不想引入第三方Django库,也可以用Bootstrap的下拉组件配合JS实现前端筛选,适合不需要后端参与的场景。

修改你的HTML模板

把原来的下拉框替换为Bootstrap的下拉结构,加上搜索输入框:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

<form method="POST" action="" enctype="multipart/form-data">
    {% csrf_token %}
    <!-- Bootstrap 下拉筛选组件 -->
    <div class="dropdown">
        <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
            {% if form.item_01.value %}{{ form.item_01.value }}{% else %}选择项目{% endif %}
        </button>
        <div class="dropdown-menu p-2" style="max-height: 300px; overflow-y: auto;">
            <input type="text" class="form-control mb-2" id="itemSearch" placeholder="搜索项目...">
            <ul class="list-unstyled" id="itemList">
                {% for value, label in form.item_01.field.choices %}
                    {% if value %}
                        <li>
                            <a class="dropdown-item" href="#" data-value="{{ value }}">{{ label }}</a>
                        </li>
                    {% endif %}
                {% endfor %}
            </ul>
        </div>
        <!-- 隐藏的原字段,用于提交表单 -->
        {{ form.item_01.as_hidden }}
    </div>
    <input type="submit" value="Submit" class="btn btn-primary mt-3">
</form>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const searchInput = document.getElementById('itemSearch');
    const itemList = document.getElementById('itemList');
    const dropdownItems = itemList.querySelectorAll('.dropdown-item');
    const hiddenField = document.querySelector('#id_item_01');
    const dropdownButton = document.querySelector('.dropdown-toggle');

    // 搜索筛选逻辑
    searchInput.addEventListener('input', function() {
        const searchTerm = this.value.toLowerCase();
        dropdownItems.forEach(item => {
            const text = item.textContent.toLowerCase();
            item.style.display = text.includes(searchTerm) ? 'block' : 'none';
        });
    });

    // 选择项后更新隐藏字段和按钮文本
    dropdownItems.forEach(item => {
        item.addEventListener('click', function(e) {
            e.preventDefault();
            const value = this.getAttribute('data-value');
            const label = this.textContent;
            hiddenField.value = value;
            dropdownButton.textContent = label;
            // 关闭下拉菜单
            const dropdown = bootstrap.Dropdown.getInstance(dropdownButton);
            dropdown.hide();
        });
    });
});
</script>

这个方案不需要修改后端代码,纯前端处理筛选,适合选项数据不会频繁变化的场景。

两种方案各有优势:django-autocomplete-light适合数据量大、需要后端动态筛选(比如关联其他条件)的场景;Bootstrap+JS方案更轻量,适合快速实现前端筛选。你可以根据自己的需求选择~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:16:38