django admin search_fields placeholder 管理后台添加搜索框提示文字

如图, Django admin后台生成的搜索框, 默认是没有提示文字的, 不够友好; 网上也没搜到什么好的示例, 于是自己动手实现了一个(要求Python3.6+,Django3.0+)

0. 已经存在的app名为carousel, 大致相当于如下操作/代码

$ python manage.py startapp carousel
# settings.py
```
INSTALLED_APPS = [
    ...
    'carousel',
]
```
# carousel/models.py
```
from django.db import models

class Carousel(models.Model):
    community = models.IntegerField('小区ID')
    
    class Meta:
        verbose_name = verbose_name_plural = '轮播设置'
```

1. 定制模板标签templatetags

mkdir -p carousel/templatetags
touch carousel/templatetags/__init__.py
touch carousel/templatetags/search_with_placeholder.py
# carousel/templatetags/search_with_placeholder.py
from django.contrib.admin.templatetags.admin_list import (
    InclusionAdminNode,
    register,
    search_form,
)


def search_form_plus(cl, search_placeholder: str = ""):
    """
    Display a search form for searching the list with placeholder.
    """
    return dict(search_form(cl), search_placeholder=search_placeholder)


@register.tag(name="search_form_plus")
def search_form_tag(parser, token):
    return InclusionAdminNode(
        parser,
        token,
        func=search_form_plus,
        template_name="search_form_plus.html",
        takes_context=False,
    )

2. 定制模板template

mkdir -p carousel/templates/admin
mkdir -p carousel/templates/custom_admin
touch carousel/templates/admin/search_form_plus.html
touch carousel/templates/custom_admin/change_list.html
<!-- carousel/templates/admin/search_form_plus.html -->
{% load i18n static %}
{% if cl.search_fields %}
<div id="toolbar"><form id="changelist-search" method="get">
<div><!-- DIV needed for valid HTML -->
<label for="searchbar"><img src="{% static "admin/img/search.svg" %}" alt="Search"></label>
<input type="text" size="40" name="{{ search_var }}" placeholder="{{ search_placeholder }}" value="{{ cl.query }}" id="searchbar" autofocus>
<input type="submit" value="{% translate 'Search' %}">
{% if show_result_count %}
    <span class="small quiet">{% blocktranslate count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktranslate %} (<a href="?{% if cl.is_popup %}_popup=1{% endif %}">{% if cl.show_full_result_count %}{% blocktranslate with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktranslate %}{% else %}{% translate "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>
</form></div>
{% endif %}
<!-- carousel/templates/custom_admin/change_list.html -->
{% extends "admin/change_list.html" %}
{% load search_with_placeholder %}

{% block search %}{% search_form_plus cl search_placeholder %}{% endblock %}

3. 定制admin.py

cat carousel/admin.py
# Django3.1
from django.contrib import admin

from .models import BoxCarousel, Carousel,


class PlaceholderMixin:
    change_list_template = "custom_admin/change_list.html"

    def changelist_view(self, request, extra_context=None):
        search_placeholder = getattr(self, "search_placeholder", False)
        if search_placeholder:
            extra_context = extra_context or {}
            extra_context["search_placeholder"] = search_placeholder
        return super().changelist_view(request, extra_context)


@admin.register(Carousel)
class CarouselAdmin(PlaceholderMixin, admin.ModelAdmin):
    search_fields = ["=community"]
    search_placeholder = "请输入小区ID"

其他列表页, 如果也想显示提示文字, 只需继承PlaceholderMixin, 然后定义search_placeholder就可以了

############################################################################

2021-10-07 补充

对于Python3.8+

mixin类可以是如下:

class PlaceholderMixin:
    """自动添加搜索框提示文字"""

    change_list_template = "custom_admin/change_list.html"

    def changelist_view(self, request, extra_context=None):
        if fs := getattr(self, "search_fields", None):
            if search_placeholder := getattr(self, "search_placeholder", True):
                extra_context = extra_context or {}
                if search_placeholder is True:
                    # 根据search_fields字段内容,自动生成提示文字
                    meta = self.model._meta
                    names = []
                    for field in fs:
                        if "__" not in field:
                            names.append(meta.get_field(field).verbose_name)
                        else:
                            # 如果搜索字段是外键,加上它的表名
                            fn, nxt, *_ = field.split("__")
                            f_obj = meta.get_field(fn)
                            n = f_obj.verbose_name
                            if remote_field := f_obj.remote_field:
                                r_meta = remote_field.model._meta
                                if (r_n := r_meta.get_field(nxt).verbose_name) != n:
                                    n += r_n
                            names.append(n)
                    search_placeholder = "请输入 " + "/".join(names)
                extra_context["search_placeholder"] = search_placeholder
        return super().changelist_view(request, extra_context)

admin自定义一个基类,然后所有要管理的表都去继承它

from django.contrib import admin
from .mixins import PlaceholderMixin


class ModelAdmin(PlaceholderMixin, admin.ModelAdmin):
    ...


class XXXAdmin(ModelAdmin):
    search_fields = ('field1', 'field2')   # 会自动根据field1和field2的verbose_name去生成提示文字

=====================================================================

2021-11-21 简化为只需pip安装,然后修改INSTALLED_APPS就可以直接引入和继承使用了

## Install

- By pypi

pip install search_placeholder

- 或 By git

pip install git+https://github.com/waketzheng/django-search-placeholder.git



## Usage

1. Add app name to settings

INSTALLED_APPS = [
    ...
    "django.contrib.admin",
    ...
    "search_placeholder",
    ...
]


2. Use search_placeholder.ModelAdmin to replace admin.ModelAdmin

from django.contrib import admin
from search_placeholder import ModelAdmin

@admin.register(ModelClass)
class ModelClassAdmin(ModelAdmin):
    # Just inherit from search_placeholder.ModelAdmin
    # it will auto generate placeholder of search input by
    # the verbose_name of 'field1' and 'field2'
    # Or you can uncomment the next line to custom placeholder
    #search_placeholder = 'Custom content'
    search_fields = ('field1', 'field2')

代码见: https://github.com/waketzheng/django-search-placeholder.git

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值