在 Django 管理员中,我如何过滤 Django 为作为“字段集”属性一部分的 ManyToManyField 显示



假设我有如下所示的模型:

class MyOtherModel(model.Model):
    name = CharField(max_length=50)
    type = CharField(max_length=5, default='A')
class MyModel(models.Model):
    name = CharField(max_length=50)
    some_m2m = ManyToManyField('MyOtherModel')

而且,在管理员中,我希望它根据类型拆分MyOtherModel实例,以显示在屏幕的不同部分,或者使用不同的标签或其他什么。

我希望能够做这样的事情(就像你可以用模型管理员的list_display属性做的那样):

class MyModelAdmin(admin.ModelAdmin):
    model = MyModel
    fieldsets = [
        (None, {
            'fields': [
                ('name', 'some_m2m_type_A', 'some_m2m_type_B',)
            ]
        })
    ]
    def some_m2m_type_A(self):
        return MyOtherModel.objects.filter(type='A')
    def some_m2m_type_B(self):
        return MyOtherModel.objects.filter(type='B')

显然,这行不通,但你明白了。


我尝试覆盖formfield_for_manytomany()

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
    if db_field == 'some_m2m_type_A':
        kwargs["queryset"] = MyOtherModel.objects.filter(type='A')
    elif db_field == 'some_m2m_type_B':
        kwargs["queryset"] = MyOtherModel.objects.filter(type='B')
    return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

类似于这个问题中的建议,但 Django 仍然出错:

字段错误: 未知字段 (some_m2m_type_A、some_m2m_type_B) 为 MyModel 指定。检查字段/字段集/排除类的属性 我的模型管理员。

它在调用formfield_for_manytomany()之前就出错了......

有没有一种简单的方法可以在 Django 管理中完成我所追求的? 还是需要大修、覆盖模板和其他难以维护的黑客攻击?

您可以通过模型定义自己的模型;

class MyOtherModel(model.Model):
    name = CharField(max_length=50)
    type = CharField(max_length=5, default='A')
class MyModel(models.Model):
    name = CharField(max_length=50)
    some_m2m = ManyToManyField('MyOtherModel', through='MyThroughModel')
class MyThroughModel(models.Model):
    mymodel = models.ForeignKey(MyModel)
    myothermodel = models.ForeignKey(MyOtherModel)

然后在admin.py;

class MyOtherModelAdmin(admin.ModelAdmin):
    model = MyOtherModel
    list_filter = ['mythroughmodel_set__myothermodel__type']

最新更新