为Django管理员创建动态JSONField属性的FIlter类

时间:2018-06-20 10:49:42

标签: python django django-admin django-filter django-mysql

让我们以下面的模型为例。

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方法,我们可以使用该方法传递动态创建的类。但是我不确定如何动态创建类。

任何帮助将不胜感激。

0 个答案:

没有答案