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

如何在自定义表单中实现Django admin页ManyToMany字段同款组件

实现Django admin同款多对多字段组件方案

Django admin 中带新增+号的多对多选择组件是通过RelatedFieldWidgetWrapper包装默认表单控件实现的,按以下步骤调整即可复现该效果:

前置确认

  • 确保Ingredient、RecipeIngredient模型已在admin后台完成注册,+号跳转的新增页为admin默认提供的页面,未注册会返回404
  • 自定义表单的前端模板需要加载admin官方的静态资源,否则组件样式和弹窗交互会失效,在模板的<head>标签中加入以下引用:
{% load static %}
<link rel="stylesheet" href="{% static 'admin/css/widgets.css' %}">
<script src="{% static 'admin/js/core.js' %}"></script>
<script src="{% static 'admin/js/vendor/jquery/jquery.js' %}"></script>
<script src="{% static 'admin/js/jquery.init.js' %}"></script>
<script src="{% static 'admin/js/admin/RelatedObjectLookups.js' %}"></script>

调整表单代码

修改你的AddRecipeForm类,手动给多对多字段的控件套上admin的包装器:

from django import forms
from django.contrib.admin.widgets import RelatedFieldWidgetWrapper
from django.contrib.admin.sites import site
from .models import Recipe

class AddRecipeForm(forms.ModelForm):
    class Meta:
        model = Recipe
        fields = ['name', 'ingredients', 'date_created']
        
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 包装ingredients字段的原有控件
        self.fields['ingredients'].widget = RelatedFieldWidgetWrapper(
            widget=self.fields['ingredients'].widget,
            rel=self.instance._meta.get_field('ingredients').remote_field,
            admin_site=site,
            can_add_related=True
        )

可选模型优化(非必须)

你当前的模型设计可以简化,直接将RecipeIngredient作为Recipe和Ingredient多对多关系的中间表,更符合Django的设计规范:

class Recipe(models.Model):
    recipe_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200)
    # 通过through参数指定中间表
    ingredients = models.ManyToManyField(Ingredient, through='RecipeIngredient')
    date_created = models.DateTimeField('Date Created')

    def __str__(self):
        return self.name

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 13:45:04