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

如何解决django-ajax-select admin面板关联元素过多页面过长问题

django-ajax-select 多对多字段展示过长问题解决方案

问题描述

我在Django admin面板中使用django-ajax-select库展示多对多关系,当前关联对象数量过多,导致页面被拉得过长。需要自定义组件,为其添加滚动条或者分页功能。

问题效果参考:
关联字段过长示例截图

当前在admin面板中引入该组件的代码如下:

form = make_ajax_form(
    MainClass,
    {
        "users": "user", # LookupChannel is registered as user
        "admins": "user",
    },
)

可行方案

方案1:添加滚动条(实现成本最低,无需修改后端逻辑)

直接通过自定义CSS给已选中项的容器设置固定高度和滚动属性,不需要改动django-ajax-select的现有逻辑,90%以上的场景用这个方案就足够。
操作步骤:

  • 给对应的admin类添加自定义Media配置,引入自定义样式文件,注意admin类要继承AjaxSelectAdmin:
from django.contrib import admin
from ajax_select.admin import AjaxSelectAdmin
from ajax_select.fields import make_ajax_form
from .models import MainClass

class MainClassAdmin(AjaxSelectAdmin):
    form = make_ajax_form(
        MainClass,
        {
            "users": "user",
            "admins": "user",
        },
    )
    class Media:
        css = {
            "all": ("css/ajax-select-fix.css",)
        }

admin.site.register(MainClass, MainClassAdmin)
  • 在项目的静态文件目录下创建css/ajax-select-fix.css,添加如下样式:
/* 命中django-ajax-select默认渲染的已选容器 */
.ui-autocomplete-multiple .deck {
    max-height: 220px; /* 可根据自身页面布局调整高度 */
    overflow-y: auto;
    padding: 4px 6px;
    border: 1px solid #e1e1e1;
    border-radius: 4px;
    margin-bottom: 8px;
}
/* 可选:适配Django admin风格美化滚动条 */
.ui-autocomplete-multiple .deck::-webkit-scrollbar {
    width: 6px;
}
.ui-autocomplete-multiple .deck::-webkit-scrollbar-thumb {
    background: #c2c2c2;
    border-radius: 3px;
}

配置完成后,已选关联项超过设置的最大高度时就会自动出现纵向滚动条,不会再拉长整个页面。


方案2:分页加载(适合单字段关联数据量超千条的场景)

如果关联对象量级大到一次性渲染所有已选项都会造成页面卡顿,可以给已选列表加分页功能,实现成本相对较高:

  • 首先自定义user对应的LookupChannel,重写获取已选对象的方法,支持分页参数:
from ajax_select import LookupChannel
from django.contrib.auth.models import User
from django.core.paginator import Paginator

class UserLookup(LookupChannel):
    model = User

    def get_objects(self, ids):
        # 保留原有的根据id匹配对象逻辑,增加分页处理
        page_num = int(self.request.GET.get("selected_page", 1))
        page_size = 20
        # 注意要优先保留当前新增的选中项,避免翻页时丢失未保存的选择
        queryset = self.model.objects.filter(pk__in=ids).order_by("username")
        paginator = Paginator(queryset, page_size)
        return paginator.page(page_num).object_list
  • 覆写django-ajax-select的多选组件模板,在已选列表底部添加分页控件,绑定翻页事件,异步拉取对应页的已选数据替换列表内容即可。
    非极端数据量场景不推荐用分页方案,滚动条方案的交互和维护成本都低很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:15:41