Django Admin下拉菜单中如何隐藏已注册的特定Celery任务

这个需求完全可以实现,核心是通过修改Admin下拉字段的选项生成逻辑,把指定任务从展示列表中剔除,不会影响Celery任务本身的注册、调度和手动调用能力。
实现方案
轻量化推荐方案
不需要重写完整的ModelForm,仅通过重写Admin类的formfield_for_choice_field方法,在字段生成下拉选项时直接过滤目标任务,改动最小且兼容性最好。
- 以项目最常用的
django-celery-results模块为例,先注销系统默认注册的任务管理类:
from django.contrib import admin from django_celery_results.models import TaskResult from django_celery_results.admin import TaskAdmin # 注销默认注册的TaskAdmin类 admin.site.unregister(TaskResult) # 配置需要隐藏的任务集合,后续新增隐藏任务直接往集合中添加全路径即可 HIDDEN_TASKS = { "main.tasks._start_proxy_loading", } @admin.register(TaskResult) class CustomTaskAdmin(TaskAdmin): def formfield_for_choice_field(self, db_field, request, **kwargs): # 仅针对task名称对应的下拉字段做过滤 if db_field.name == "task": field = super().formfield_for_choice_field(db_field, request, **kwargs) # 从选项列表中剔除所有需要隐藏的任务 field.choices = [ choice for choice in field.choices if choice[0] not in HIDDEN_TASKS ] return field return super().formfield_for_choice_field(db_field, request, **kwargs)
- 如果项目使用的是老版本
djcelery模块,逻辑完全一致,只需要把上述代码中注销、注册的模型和Admin类,替换为djcelery对应的TaskState、TaskAdmin即可。
自定义Form批量过滤方案
如果需要按规则批量过滤(比如所有内部以下划线开头的任务全部隐藏),可以自定义完整的ModelForm,从Celery已注册任务列表阶段就做筛选:
from django import forms from celery import current_app # 配置需要过滤的任务名前缀,支持匹配多组规则 HIDDEN_TASK_PREFIXES = ( "main.tasks._", "celery.", ) class FilteredTaskForm(forms.ModelForm): task = forms.ChoiceField(choices=[]) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 拉取Celery全量已注册任务 all_registered_tasks = sorted(current_app.tasks.keys()) # 按照前缀规则批量过滤可用任务 available_tasks = [ (task_name, task_name) for task_name in all_registered_tasks if not task_name.startswith(HIDDEN_TASK_PREFIXES) ] self.fields["task"].choices = [("", "---------")] + available_tasks # 替换原有Admin类绑定的Form即可生效 @admin.register(TaskResult) class CustomTaskAdmin(TaskAdmin): form = FilteredTaskForm
注意:上述两种方案仅实现前端下拉选项的隐藏,不会从Celery的任务注册表中删除对应任务,你仍然可以通过
app.send_task("main.tasks._start_proxy_loading")的方式正常触发任务,不会破坏原有业务逻辑。
内容的提问来源于stack exchange,提问作者Ciganeshima
相关产品推荐
相关产品推荐

