如何在Django模板中将django-multiselectfield值渲染到Bootstrap4多选下拉框
问题根因
你当前的代码有4处核心错误导致样式不生效:
- 模型层
TEAM选项定义错误,且会出现选项不动态更新的问题 - 表单层没有为多选字段指定
SelectMultiple组件,默认渲染为复选框组 - 模板层手动嵌套了多余的
<select>标签,和Django自动渲染的表单元素冲突 - 同时引入了
select2和bootstrap-select两个同类下拉组件,存在依赖冲突
分步修改方案
1. 修正 models.py
原代码直接在模型类属性中查询Country.objects.all(),Django启动时只会执行一次,后续新增的国家不会同步到选项中,且选项值直接存储模型对象不符合字段要求,修改如下:
from django.db import models from multiselectfield import MultiSelectField class Country(models.Model): name = models.CharField(max_length=40) def __str__(self): return self.name def get_country_choices(): # 用可调用对象动态生成选项,保证新增国家实时同步 return tuple((ob.id, ob.name) for ob in Country.objects.all()) class Person(models.Model): name = models.CharField(max_length=124) # choices传入可调用对象,值存国家ID,显示名用国家名称 southasia=MultiSelectField(max_length=200, choices=get_country_choices) def __str__(self): return self.name
2. 修正 forms.py
为southasia字段指定多选下拉组件,添加bootstrap-select需要的属性:
from django import forms from .models import Person class PersonCreationForm(forms.ModelForm): class Meta: model = Person fields = '__all__' widgets = { 'southasia': forms.SelectMultiple(attrs={ 'class': 'selectpicker', 'multiple': True, 'data-live-search': 'true' }) } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)
3. 修正模板文件
删除多余的手动<select>标签,移除冲突的select2依赖,修改如下:
{% load crispy_forms_tags %} <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Dependent Dropdown in Django</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.css" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js"></script> </head> <body> <h2>Person Form</h2> <form method="post"> {% csrf_token %} {{ form.name|as_crispy_field }} <!-- 直接渲染字段即可,表单组件已经在forms.py里配置了对应属性 --> {{ form.southasia|as_crispy_field }} <input type="submit" value="Submit" class="btn btn-primary mt-3"> </form> <script> $('.selectpicker').selectpicker(); </script> </body> </html>
修改完成后重新启动服务即可看到bootstrap样式的多选下拉框,选中的值提交后会自动存入MultiSelectField字段中。
内容的提问来源于stack exchange,提问作者mhhabib
相关产品推荐
相关产品推荐

