Django管理员内联自定义查询集

kla*_*ern 9 django

我有两个型号:

class Parent:
   ...

class Child:
   parent = models.ForeignKey(Parent)
Run Code Online (Sandbox Code Playgroud)

Parent的模型管理员中,我想用自定义查询集显示Child的内联,而不仅仅是通过fk字段​​与父项相关的内联.

我试过了:

class ChildInline(admin.TabularInline):
   model = Child
   def get_queryset(self, request):
      return Child.objects.filter(<my custom filter>)

class ParentAdmin(admin.ModelAdmin):
   inlines = [ChildInline]
Run Code Online (Sandbox Code Playgroud)

但是内联中显示的唯一子项是那些满足两个过滤器的子项:与FK +我的自定义过滤器的父项相关.

是否有可能做到这一点?

编辑:

我现在看到的是BaseInlineFormSet正在过滤我创建的查询集,只保留与父项相关的子项,任何想法如何避免这种情况?

django/forms/models.py

class BaseInlineFormSet(BaseModelFormSet):
    ...
    if self.instance.pk is not None:
       qs = queryset.filter(**{self.fk.name: self.instance})
    ...
Run Code Online (Sandbox Code Playgroud)

Sat*_*dra 10

您必须覆盖__init__()BaseInlineFormSet的方法并更新它们的查询集.

from django.forms.models import BaseInlineFormSet

class ChildInlineFormSet(BaseInlineFormSet):

    def __init__(self, *args, **kwargs):
        super(ChildInlineFormSet, self).__init__(*args, **kwargs)
        # Now we need to make a queryset to each field of each form inline
        self.queryset = Child.objects.filter(<my custom filter>)
Run Code Online (Sandbox Code Playgroud)

然后使用ChildInlineFormSet初始化formset属性

class ChildInline(admin.TabularInline):
    model = Child
    formset = ChildInlineFormSet
    extra = 0
Run Code Online (Sandbox Code Playgroud)


Lin*_*yen 7

旧答案不再适用于当前的 Django 2.2 或 3,因为 self.queryset 被忽略

当前的解决方案是覆盖get_queryset

from django.forms.models import BaseInlineFormSet

class ChildInlineFormSet(BaseInlineFormSet):

    def get_queryset(self):
        qs = super(ChildInlineFormSet, self).get_queryset()
        return qs.filter(<custom query filters>)

class ChildInline(admin.TabularInline):
    model = Child
    formset = ChildInlineFormSet
    extra = 0
Run Code Online (Sandbox Code Playgroud)

  • @EugZol您可以参考这个关于如何获取父对象的答案/sf/answers/3053201861/ (2认同)