In the Django admin, I have an Inline, and I would like to filter the list of rows by the parent object.
I can override get_queryset(request)
in my Inline, but I don't have access to the parent object.
This snippet is from Django's options.py:
def get_formset_kwargs(self, request, obj, inline, prefix):
formset_params = {
"instance": obj,
"prefix": prefix,
"queryset": inline.get_queryset(request),
}
This would by immediately solved, if Django would provide obj
as an argument to inline.get_queryset()
.
How to implement a get_queryset()
of an InlineModelAdmin
instance, so that it has access to obj
?
class ChildInline(admin.TabularInline):
...
def get_queryset(self, request):
???? how to get the parent object?
CodePudding user response:
These lines of code are the implementation of how inline admin instance are instantiate in Django
def get_inline_instances(self, request, obj=None):
inline_instances = []
for inline_class in self.get_inlines(request, obj):
inline = inline_class(self.model, self.admin_site)
if request:
if not (
inline.has_view_or_change_permission(request, obj)
or inline.has_add_permission(request, obj)
or inline.has_delete_permission(request, obj)
):
continue
if not inline.has_add_permission(request, obj):
inline.max_num = 0
inline_instances.append(inline)
return inline_instances
as you can see there is no obj passed to the inline_class so normally you can't access the parent instance.
Override this function in your parent model's admin class and use assigned attribute 'parent_obj' in your get_queryset method will make it work.
# parent admin class
def get_inline_instances(self, request, obj=None):
inline_instances = super().get_inline_instances(request, obj)
for inline_instance in inline_instances:
inline_instance.parent_obj = obj
return inline_instances
# inline admin class
def get_queryset(self, request):
self.parent_obj # you can now access your parent obj
CodePudding user response:
I found this dirty hack. In my case Event
is the parent-model:
class ChildInline(admin.TabularInline):
...
def get_queryset(self, request):
# dirty hack to get the parent-object (event).
# Please fix it and tell me,
# if you know a better way to get it.
event_id = request.path_info.split('/')[-2]
event = Event.objects.get(id=event_id)
...