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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:52:46