如何在Django 1.11 Admin中扩展filter_horizontal显示事件日期
解决方案
当然可行!有两种常用的方式可以实现这个需求,你可以根据是否需要全局修改Event的显示格式来选择:
方法一:修改Event模型的__str__方法(全局生效)
如果希望整个项目里Event实例的显示都采用「标题 - 日期」的格式,直接修改Event模型的__str__方法是最简单的方式:
假设你的Event模型包含title和date字段(根据需求推测),修改代码如下:
from django.db import models class Event(models.Model): title = models.CharField(max_length=500) date = models.DateField() # 若实际是DateTimeField也可以,后续调整格式化规则即可 # 其他字段... def __str__(self): # 这里用%Y-%m-%d作为日期格式示例,你可以根据需求自定义格式 return f"{self.title} - {self.date.strftime('%Y-%m-%d')}"
修改完成后,filter_horizontal中的事件选项会自动显示为「事件标题 - 事件日期」的格式,不需要改动ProductAdmin的代码。
方法二:仅在ProductAdmin中自定义显示(局部生效)
如果你不想全局修改Event的__str__方法,只希望在ProductAdmin的filter_horizontal里特殊显示,可以通过自定义表单字段的label_from_instance方法实现:
步骤1:自定义Product的Admin表单
在你的admin.py文件中,创建一个继承自ModelForm的自定义表单,并重写events字段的显示逻辑:
from django import forms from django.contrib import admin from .models import Product, Event from your_app_module import TranslationAdmin # 替换为TranslationAdmin的实际导入路径 class ProductAdminForm(forms.ModelForm): # 自定义events字段的查询集和widget,保持filter_horizontal的样式 events = forms.ModelMultipleChoiceField( queryset=Event.objects.all(), widget=admin.widgets.FilteredSelectMultiple("Events", is_stacked=False), required=False ) def label_from_instance(self, obj): # 定义每个事件选项的显示文本 return f"{obj.title} - {obj.date.strftime('%Y-%m-%d')}" class Meta: model = Product fields = "__all__"
步骤2:在ProductAdmin中绑定自定义表单
将刚才创建的自定义表单关联到你的ProductAdmin类:
class ProductAdmin(TranslationAdmin): form = ProductAdminForm filter_horizontal = ('events',) # 保留该配置以确保filter_horizontal的样式生效
额外说明
- 如果你的Event模型使用了翻译插件(比如django-modeltranslation),
obj.title会自动适配后台当前的语言版本,无需额外处理。 - 日期格式化规则可以按需调整,比如如果是DateTimeField,可改为
%Y-%m-%d %H:%M来显示时分。 - 这两种方法在Django 1.11版本中完全兼容,可以放心使用。
内容的提问来源于stack exchange,提问作者user9192656
相关产品推荐
相关产品推荐

