3

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

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。灵感来自这里

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'

然后在 list_filter 中使用上面派生的 ExtraFilter 类,如下所示StudentAdmin

class StudentAdmin(admin.ModelAdmin):
    list_filter = ('standard', ExtraFilter)

现在,上面的片段工作得很好。但我想要实现的是'To have dynamic each extra's attribute filter'.

我可以在单独模型中的某处维护列表,在那里我可以输入属性的名称,例如...... ['buys', 'country'](想法是我可以获取活动属性名称的列表并使用它 get_list_filter 方法动态创建类)等。

现在,只有'Buys'过滤器。这将填充从每个学生购买的汽车的选择。但如果'country'在单人模式中添加,则应添加“国家”过滤器。每个学生可以在额外字段中添加多个/多个属性。

因此,只'json_field_property_name'需要动态地传递给新的派生类即可list_filter。我们也有get_list_filter方法 from admin.ModelAdmin,我们可以使用它来传递动态创建的类。但我不太确定如何即时创建课程。

任何帮助,将不胜感激。

4

0 回答 0