【问题标题】:Django admin, filter objects for inline formsetDjango admin,为内联表单集过滤对象
【发布时间】:2011-01-07 07:15:01
【问题描述】:

我有一个内联表单集,我想排除一些模型对象在表单集中显示。

例如。模型 B 与模型 A 具有外键,因此它是 1:n(A 对象有许多 B 对象)关系。现在在 A 管理编辑页面上,我有 B 的内联。我想知道是否有可能在呈现内联表单集之前以某种方式过滤 B 对象的列表,因此并非所有与 A 相关的 B 对象都进入表单集。

【问题讨论】:

    标签: django django-admin django-forms


    【解决方案1】:

    回答自己的问题可能看起来有点奇怪,但我找到了另一个解决方案;)

    向表单集提供自定义查询集时出现问题,在内联表单集的情况下没有钩子。所以我继承了 BaseInlineFormSet 并覆盖了 get_queryset 方法。然后我只需在 InlineModelAdmin 中提供这个表单集就完成了。

    例子:

    class MyFormSet(BaseInlineFormSet):
        def get_queryset(self):
            if not hasattr(self, '_queryset'):
                qs = super(MyFormSet, self).get_queryset().filter(main=False)
                self._queryset = qs
            return self._queryset
    

    和管理类:

    class MyInline(admin.TabularInline):
        model = m.MyModel
        formset =  MyFormSet
        ...
    

    【讨论】:

    • 非常好——这正是我想要的。使用私有属性 '_queryset' 可以阻止 SQL 查询在每页触发数十次。非常好。
    【解决方案2】:

    您可以为您的模型编写自己的管理器(formset 专用)并使用它。

    http://docs.djangoproject.com/en/dev/topics/db/managers/

    【讨论】:

    • 非常感谢。这看起来是一个不错的解决方案,尽管我将不得不在所有其他地方使用另一个(非默认)管理器,因为我需要那些被过滤掉的对象,而不是在管理页面中。很遗憾,没有提供自定义的管理选项,而不是默认的内联管理器。
    • 好吧,我发现我可以通过继承 BaseInlineFormSet (docs.djangoproject.com/en/1.1/topics/forms/modelforms/…) 为内联提供非默认查询集/管理器,然后通过“formset”属性将此表单集提供给 InlineModelAdmin。不错!
    • 如果您编写自己的管理器,如果您的模型也在 Django Admin 中注册,您可能需要做更多的解决方法。
    【解决方案3】:

    在 Django 3 中,您应该使用 formfield_for_foreignkey。

    这是一个工作示例:

    class CaracteristiqueInline(admin.TabularInline):
      model = Caracteristique
      formset = FiltreCaracteristiqueInline
    
      def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "id_Champ": # The FK in my table Caracteristique
            kwargs["queryset"] = Champ.objects.filter(est_DC_Champ=False)
            # Champ is the parent table of Caracteristique
            # est_DC_Champ is a field of the table Champ
        return super().formfield_for_foreignkey(db_field, request, **kwargs)
      extra = 0
    

    这样,在您的表格视图中,您的 FK 字段下拉列表中的选项将被过滤。

    【讨论】:

      猜你喜欢
      • 2011-07-11
      • 1970-01-01
      • 2020-04-16
      • 2011-07-25
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 2021-09-22
      • 2021-01-07
      相关资源
      最近更新 更多