django admin inlines:从formfield_for_foreignkey获取对象

sog*_*ing 16 python django django-admin

我试图在django管理内联中过滤外键字段中显示的选项.因此,我想访问正在编辑的父对象.我一直在研究,但找不到任何解决方案.

class ProjectGroupMembershipInline(admin.StackedInline):
    model = ProjectGroupMembership
    extra = 1
    formset = ProjectGroupMembershipInlineFormSet
    form = ProjectGroupMembershipInlineForm

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        if db_field.name == 'group':
            kwargs['queryset'] = Group.objects.filter(some_filtering_here=object_being_edited)
        return super(ProjectGroupMembershipInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

我已经验证了编辑对象时kwargs是空的,所以我无法从那里获取对象.

有什么帮助吗?谢谢

mko*_*nen 16

另一种方式,恕我直言,感觉比清洁,但类似于@ erichonkanen的答案是这样的:

class ProjectGroupMembershipInline(admin.StackedInline):
    # irrelevant bits....

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "group":
            try:
                parent_obj_id = request.resolver_match.args[0]
                kwargs["queryset"] = Group.objects.filter(some_filtering_here=parent_obj_id)
            except IndexError:
                pass
        return super(
            ProjectGroupMembershipInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)


小智 13

@mkoistinen 提供的答案很好,但是 django 将父 ID 存储在 kwargs 而不是 args 中,因此像这样提取它是正确的。

parent_id = request.resolver_match.kwargs.get('object_id')
Run Code Online (Sandbox Code Playgroud)


dsh*_*hap 10

要过滤管理内联中外键字段的可用选项,我会覆盖表单,以便我可以更新表单字段的queryset属性.这样您就可以访问self.instance表单中正在编辑的对象.所以像这样:

class ProjectGroupMembershipInlineForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ProjectGroupMembershipInlineForm, self).__init__(*args, **kwargs)
        self.fields['group'].queryset = Group.objects.filter(some_filtering_here=self.instance)
Run Code Online (Sandbox Code Playgroud)

formfield_for_foreignkey如果您执行上述操作,则无需使用它,它应该完成您所描述的内容.

  • 您应该进一步指出**父对象**应该可以作为self.instance上的字段使用,该字段不是父对象,而是**内联对象**.但是,这不适用于新的内联对象,因为该关系尚不存在. (4认同)

小智 5

我能够通过使用formfield_for_foreignkey并从url中剥离对象ID来解决它.这不是获取ID的最性感方式,但Django还没有提供对admin对象上的对象ID的访问权限(它应该).

class ObjectAdmin(admin.ModelAdmin):

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        obj_id = request.META['PATH_INFO'].rstrip('/').split('/')[-1]
        if db_field.name == 'my_field' and obj_id.isdigit():
            obj = self.get_object(request, obj_id)
            if obj:
                kwargs['queryset'] = models.Object.objects.filter(field=obj)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)