如何为Django Admin的Select2自动完成字段设置动态默认值
实现Django Admin自动填充上次选择的产品作为默认值
步骤1:修改Admin类,存储并读取上次选择的产品ID
在HeadFlowDatasetAdmin中重写相关方法,利用用户Session保存最近选择的产品ID,并在新增页面加载时设置初始值:
from django.contrib.admin.options import get_content_type_for_model from django.http import HttpResponseRedirect from django.db.models.functions import Lower class HeadFlowDatasetAdmin(admin.ModelAdmin): list_display = ("product", "head", "flow") fields = ("product", "head", "flow") autocomplete_fields = ["product"] def get_ordering(self, request): return [Lower("product__pump_name"), "head"] def add_view(self, request, form_url='', extra_context=None): # 从Session读取上次保存的产品ID last_product_id = request.session.get('last_headflow_product_id') extra_context = extra_context or {} if last_product_id: extra_context['initial_product_id'] = last_product_id return super().add_view(request, form_url, extra_context) def change_view(self, request, object_id, form_url='', extra_context=None): # 修改数据时,更新Session中的产品ID if request.method == 'POST': product_id = request.POST.get('product') if product_id: request.session['last_headflow_product_id'] = product_id return super().change_view(request, object_id, form_url, extra_context) def save_model(self, request, obj, form, change): # 新增数据时,将当前产品ID存入Session if not change: request.session['last_headflow_product_id'] = str(obj.product.id) super().save_model(request, obj, form, change)
步骤2:添加前端JS处理Select2默认值
由于autocomplete字段是异步加载的Select2组件,需要通过JS在页面加载后触发搜索并选中目标产品。首先在Admin类中添加媒体文件引用:
class HeadFlowDatasetAdmin(admin.ModelAdmin): # ... 已有代码 ... class Media: js = ('admin/js/headflow_default_product.js',)
然后在项目的static/admin/js/目录下创建headflow_default_product.js文件,内容如下:
document.addEventListener('DOMContentLoaded', function() { // 获取模板传递的初始产品ID const initialProductId = document.querySelector('#initial_product_id')?.value; if (!initialProductId) return; const productField = document.querySelector('#id_product'); if (!productField) return; // 等待Select2初始化完成 setTimeout(function() { const $productSelect = $(productField); if ($productSelect.data('select2')) { // 触发搜索加载选项,再选中目标ID $productSelect.select2('search', ''); $productSelect.on('select2:open', function() { setTimeout(function() { $productSelect.val(initialProductId).trigger('change'); $productSelect.select2('close'); }, 100); }); } }, 500); });
步骤3:传递初始值到模板
创建自定义的change_form模板templates/admin/[你的应用名]/headflowdataset/change_form.html(替换[你的应用名]为实际应用名称):
{% extends "admin/change_form.html" %} {% block extrahead %} {{ block.super }} {% if initial_product_id %} <input type="hidden" id="initial_product_id" value="{{ initial_product_id }}"> {% endif %} {% endblock %}
注意事项
- 确保Django Session功能正常启用(默认已配置)
- UUID格式的产品ID需以字符串形式存储和读取,避免序列化问题
- 可根据页面加载速度调整JS中的延迟时间(500ms、100ms),确保Select2初始化完成
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

