让我们以下面的模型为例。
from django_mysql.models import JSONField
class Student(models.Model):
standard = models.CharField(_('Standard'), max_length=10, null=True, blank=True, choices=STANDARD_CHOICES)
extra = JSONField()
# example data in above field might be as below
# {"name": "Bob", "buys": "tesla", "country": "India"}
# {"name": "Sam", "buys": "lamborgini", "country": "England"}
# {"name": "Izzy", "buys": "tesla", "country": "Egypt"}
这是我的JSONField过滤器的JSONFieldFilter BaseClass。 Inspired from here
class JSONFieldFilter(SimpleListFilter):
def __init__(self, *args, **kwargs):
super(JSONFieldFilter, self).__init__(*args, **kwargs)
assert hasattr(self, 'title'), (
'Class {} missing "title" attribute'.format(self.__class__.__name__)
)
assert hasattr(self, 'parameter_name'), (
'Class {} missing "parameter_name" attribute'.format(self.__class__.__name__)
)
assert hasattr(self, 'json_field_name'), (
'Class {} missing "json_field_name" attribute'.format(self.__class__.__name__)
)
assert hasattr(self, 'json_field_property_name'), (
'Class {} missing "json_field_property_name" attribute'.format(self.__class__.__name__)
)
def lookups(self, request, model_admin):
field_value_set = set()
for data in Student.objects.values_list(
self.json_field_name, flat=True):
if self.json_field_property_name in data:
field_value_set.add(data[self.json_field_property_name])
return [(v, v) for v in field_value_set]
def queryset(self, request, queryset):
if self.value():
json_field_query = {"{}__{}".format(self.json_field_name, self.json_field_property_name): self.value()}
return queryset.filter(**json_field_query)
else:
return queryset
并派生如下的静态过滤器类。
class ExtraFilter(JSONFieldFilter):
title = _('Car bought')
parameter_name = 'CarBought'
json_field_name = 'extra'
json_field_property_name = 'buys'
然后在上方的{_1}}类的list_filter中使用上面派生的ExtraFilter类。
StudentAdmin
现在,上面的代码片段非常完美。但是我想要实现的是class StudentAdmin(admin.ModelAdmin):
list_filter = ('standard', ExtraFilter)
。
我可以仅在单独模型中的某个位置维护列表,在其中可以输入诸如... 'To have dynamic each extra's attribute filter'
之类的属性的名称(想法是,我可以获取活动属性名称的列表并使用它的get_list_filter方法在其上创建类飞)等。
目前,只有['buys', 'country']
个过滤器。它将填充从每个学生那里购买的汽车的选择。但是,如果在单独模型中添加了'Buys'
,则应添加“国家”过滤器。每个学生可以在额外字段中添加多个属性。
因此,只有'country'
是动态的,并传递给'json_field_property_name'
的新派生类。此外,我们还有list_filter
中的get_list_filter
方法,我们可以使用该方法传递动态创建的类。但是我不确定如何动态创建类。
任何帮助将不胜感激。