Django3.1 admin.py中如何为ModelAdmin搜索字段添加placeholder
Django 3.1 Admin 搜索框自定义Placeholder实现方案
直接在ModelAdmin类中添加 search_input_placeholder 配置项在Django 3.1中没有内置支持,需要通过极少量的自定义代码实现和你期望完全一致的配置式写法,不需要侵入业务逻辑。
核心实现逻辑
Django Admin的搜索框渲染依赖两处核心环节:
- ChangeList类负责向搜索模板传递上下文变量
admin/search_form.html模板片段负责渲染搜索输入框
只要把自定义的placeholder值通过上下文透传到模板中,就能直接在input标签上挂载对应属性,全程不需要修改Django源码。
分步实现代码
- 第一步:编写可复用的自定义ChangeList类,读取ModelAdmin上配置的placeholder值
from django.contrib.admin.views.main import ChangeList from django.utils.translation import gettext_lazy as _ class CustomSearchChangeList(ChangeList): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 从关联的ModelAdmin实例上读取自定义placeholder,未配置时用默认提示 model_admin = kwargs.get('model_admin') or args[7] self.search_placeholder = getattr(model_admin, 'search_input_placeholder', _('Search'))
- 第二步:编写通用的自定义ModelAdmin基类,替换默认的ChangeList逻辑
from django.contrib.admin import ModelAdmin class SearchPlaceholderModelAdmin(ModelAdmin): # 开放可配置的placeholder属性,默认值为通用搜索提示 search_input_placeholder = _('Search') def get_changelist(self, request, **kwargs): # 绑定自定义的ChangeList类 return CustomSearchChangeList
- 第三步:替换默认的搜索表单模板片段
在项目的templates/admin/目录下新建search_form.html,复制Django官方默认的搜索表单模板内容,在输入框标签中添加placeholder变量:
{% load i18n static %} {% if cl.search_fields %} <div id="toolbar"> <form id="changelist-search" method="get"> <div> <label for="searchbar"><img src="{% static 'admin/img/search.svg' %}" alt="Search"></label> <!-- 仅需在原有input标签中新增*placeholder*属性绑定即可 --> <input type="text" size="40" name="{{ search_var }}" value="{{ cl.query }}" id="searchbar" placeholder="{{ cl.search_placeholder }}" {% if cl.search_help_text %} aria-describedby="searchbar_helptext"{% endif %} > <input type="submit" value="{% trans 'Search' %}"> <!-- 原有模板的其他逻辑保持不变 --> {% if show_result_count %} <span class="small quiet"> {% blocktrans count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}{{ is_popup_var }}=1{% endif %}"> {% if cl.show_full_result_count %}{% blocktrans with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktrans %}{% else %}{% trans "Show all" %}{% endif %} </a>) </span> {% endif %} {% for pair in cl.params.items %} {% if pair.0 != search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}">{% endif %} {% endfor %} </div> {% if cl.search_help_text %} <br class="clear"> <div class="help" id="searchbar_helptext">{{ cl.search_help_text|safe }}</div> {% endif %} </form> </div> {% endif %}
实际使用方式
配置完成后,在具体的模型Admin中,完全按照你期望的写法编写即可,不需要额外修改其他逻辑:
@admin.register(Community) class MyAdmin(SearchPlaceholderModelAdmin): list_display = ['community'] search_fields = ['community'] # 自定义搜索框的placeholder提示 search_input_placeholder = 'Please input community id'
注意事项
- 该实现完全基于Django 3.1的公开API开发,不会被小版本升级破坏
- 如果不想全局替换搜索模板,也可以为单个ModelAdmin单独通过
change_list_template属性指定自定义列表页模板,仅替换该模型的搜索框提示 - 自定义ChangeList的初始化参数需要和Django 3.1的父类保持完全一致,避免出现参数不匹配的报错
内容的提问来源于stack exchange,提问作者Waket Zheng
相关产品推荐
相关产品推荐

