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

Django中Crispy Forms的ChoiceField下拉选项悬停样式修改

解决方案

首先明确:原生HTML的<option>元素的:hover伪类在多数现代浏览器中不被支持,这就是你直接写select option:hover无效的核心原因。另外,你代码里的类名存在拼写错误(boostrap-select应为bootstrap-select),如果使用了bootstrap-select插件,它会将原生select转换为自定义的<ul>/<li>结构模拟下拉选项,需要针对插件生成的DOM写CSS。

情况1:使用bootstrap-select插件

1. 修正forms.py中的类名拼写

select_cancer = forms.ChoiceField(
    label='Cancer',
    choices=ExtractCancer(),
    required=False,
    widget=forms.Select(attrs={'class':'bootstrap-select'})  # 修正拼写错误
)

2. 编写插件对应的CSS

/* 下拉框容器样式 */
.bootstrap-select {
  background-color: black;
  color: white;
}
/* 下拉菜单容器 */
.bootstrap-select .dropdown-menu {
  background-color: black;
}
/* 下拉选项默认样式 */
.bootstrap-select .dropdown-menu > li > a {
  color: white;
  background-color: black;
}
/* 鼠标悬停时的选项样式 */
.bootstrap-select .dropdown-menu > li > a:hover {
  background-color: blue;
  color: white;
}

注意:确保已正确引入bootstrap-select的官方CSS和JS文件,否则插件无法正常渲染自定义结构。

情况2:使用原生Bootstrap(无额外插件)

原生select的option悬停无法直接用CSS控制,建议改用Bootstrap的Dropdown组件自定义下拉菜单,实现完全样式控制:

1. 自定义Widget(forms.py)

from django.forms.widgets import Widget
from django.utils.safestring import mark_safe

class CustomCancerDropdown(Widget):
    def __init__(self, choices, attrs=None):
        super().__init__(attrs)
        self.choices = choices

    def render(self, name, value, attrs=None, renderer=None):
        options_html = ""
        selected_label = "Select Cancer"
        # 生成下拉选项HTML
        for val, label in self.choices:
            selected_class = "selected" if val == value else ""
            if val == value:
                selected_label = label
            options_html += f'<li><a class="dropdown-item {selected_class}" data-value="{val}">{label}</a></li>'
        
        # 返回带隐藏input的自定义下拉结构(用于提交表单值)
        return mark_safe(f'''
            <div class="dropdown">
                <button class="btn custom-dropdown-btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                    {selected_label}
                </button>
                <ul class="dropdown-menu custom-dropdown-menu">
                    {options_html}
                </ul>
                <input type="hidden" name="{name}" value="{value or ''}">
            </div>
        ''')

# 在表单中使用自定义Widget
select_cancer = forms.ChoiceField(
    label='Cancer',
    choices=ExtractCancer(),
    required=False,
    widget=CustomCancerDropdown(choices=ExtractCancer())
)

2. 自定义CSS样式

/* 下拉按钮样式 */
.custom-dropdown-btn {
    background-color: black;
    border-color: black;
    color: white;
}
.custom-dropdown-btn:hover {
    background-color: black;
    border-color: black;
}
/* 下拉菜单容器 */
.custom-dropdown-menu {
    background-color: black;
}
/* 下拉选项默认样式 */
.custom-dropdown-menu .dropdown-item {
    color: white;
}
/* 鼠标悬停样式 */
.custom-dropdown-menu .dropdown-item:hover {
    background-color: blue;
    color: white;
}
/* 选中选项的高亮样式 */
.custom-dropdown-menu .dropdown-item.selected {
    background-color: blue;
}

3. 添加JavaScript同步选中值

document.addEventListener('DOMContentLoaded', function() {
    const dropdownItems = document.querySelectorAll('.custom-dropdown-menu .dropdown-item');
    const hiddenInput = document.querySelector('input[name="select_cancer"]');
    const dropdownBtn = document.querySelector('.custom-dropdown-btn');

    dropdownItems.forEach(item => {
        item.addEventListener('click', function() {
            // 更新选中状态
            dropdownItems.forEach(i => i.classList.remove('selected'));
            this.classList.add('selected');
            // 同步隐藏input的表单值
            hiddenInput.value = this.getAttribute('data-value');
            // 更新按钮显示文本
            dropdownBtn.textContent = this.textContent;
        });
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:20:27