This is an old question, but I do something like this recently, so I share.
@Risadinha answer needs modification since, as @Joren pointed, the reverse function has to find corresponding pattern somwhere in the urls. So, you can reverse only part which Django "knows". The rest of the url has to be added idenpendently.
#in admin.py in modelBAdmin class
class ModelBAdmin(admin.ModelAdmin):
...
list_filter = (..., 'modelA__id', ...)
...
# in admin.py in ModelAAdmin class
class ModelAAdmin(admin.ModelAdmin):
...
fields = (..., '_link_to_B', ...)
readonly_fields = (..., '_link_to_B', ...)
def _link_to_B(self, obj):
model_cls = modelB
reverse_url = reverse('admin:{}_{}_changelist'.format(model_cls._meta.app_label, _model_cls._meta.model_name))
changelist_filtered_url = '{}?modelA__id={}'.format(reverse_url, obj.id)
return mark_safe('<a href="{}">Link text</a>'.format(changelist_filtered_url))
Notice, that there is a filter in the modelB corresponding to "modelA__id' in the url.