如何在ModelForm中使用Django后台管理的多对多选择组件?
在自定义ModelForm中使用Django Admin式的分组多选组件
你要的是Django Admin中Group权限选择的那种带分组过滤的多选组件,它是Django内置的FilteredSelectMultiple widget,下面是具体实现步骤:
1. 导入并配置ModelForm
首先从django.contrib.admin.widgets导入FilteredSelectMultiple,然后在你的ModelForm中为多对多字段指定这个widget:
假设你的模型结构是这样的:
# models.py from django.db import models class FirstModel(models.Model): name = models.CharField(max_length=100) category = models.CharField(max_length=100) # 用于分组的字段,类似权限的content_type def __str__(self): return self.name class SecondModel(models.Model): name = models.CharField(max_length=100) related_first_models = models.ManyToManyField(FirstModel) def __str__(self): return self.name
对应的ModelForm配置:
# forms.py from django import forms from django.contrib.admin.widgets import FilteredSelectMultiple from .models import SecondModel class SecondModelForm(forms.ModelForm): class Meta: model = SecondModel fields = ['name', 'related_first_models'] widgets = { 'related_first_models': FilteredSelectMultiple( verbose_name='关联的FirstModel对象', is_stacked=False, # False是横向分栏,和Admin Group页面布局一致;True是纵向堆叠 ) }
2. 在模板中加载必要的静态资源
这个组件依赖Django Admin的JS和CSS文件,需要在渲染表单的模板中添加以下内容:
<!-- templates/your_template.html --> {% load static %} <link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}"> <script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script> <script type="text/javascript" src="{% static 'admin/js/SelectBox.js' %}"></script> <script type="text/javascript" src="{% static 'admin/js/SelectFilter2.js' %}"></script> <!-- 初始化组件 --> <script type="text/javascript"> django.jQuery(document).ready(function(){ // 替换成你的字段ID,比如id_related_first_models django.jQuery('#id_related_first_models').filterSelect(); }); </script> <!-- 渲染表单 --> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">提交</button> </form>
3. 视图中正常处理表单
在视图中按常规方式使用这个ModelForm即可:
# views.py from django.shortcuts import render, redirect from .forms import SecondModelForm def create_second_model(request): if request.method == 'POST': form = SecondModelForm(request.POST) if form.is_valid(): form.save() return redirect('some_success_url') else: form = SecondModelForm() return render(request, 'your_template.html', {'form': form})
注意事项
- 如果需要像权限那样按分类分组展示
FirstModel,要确保模型中有对应的分类字段,Django会自动根据模型的__str__和分类字段进行分组 - 不同Django版本的静态资源路径可能略有差异,若组件显示异常可检查静态资源是否正确加载
is_stacked参数控制组件布局,按需调整即可
内容的提问来源于stack exchange,提问作者Felipe Martins
相关产品推荐
相关产品推荐

