我正在尝试过滤django admin内联中的foreignkey字段中显示的选项。因此,我想访问正在编辑的父对象。我一直在研究,但找不到任何解决方案。
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)
我已经确认编辑对象时kwargs是空的,所以我无法从那里获取对象。
请帮忙吗?感谢
答案 0 :(得分:11)
另一种方式,恕我直言,感觉比较干净,但与@ 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)
答案 1 :(得分:9)
要过滤管理内联中可用于外键字段的选项,我会覆盖该表单,以便我可以更新表单字段的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)
如果您执行上述操作,则无需使用formfield_for_foreignkey
,它应该完成您所描述的内容。
答案 2 :(得分: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)
答案 3 :(得分:0)
@mkoistinen提供的答案很好,但django将父代ID存储在kwargs中而不是args中,因此像这样提取它是正确的。
parent_id = request.resolver_match.kwargs.get('object_id')
答案 4 :(得分:0)
这是我想出的解决方案,看起来很干净
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "group":
parent_id = request.resolver_match.kwargs['object_id']
kwargs["queryset"] = Group.objects.filter(some_column=parent_id)
return super().formfield_for_foreignkey(db_field, request, **kwargs)