4

How do you lookup the admin change url for an arbitrary model?

If I know the model, I can get the url by doing something like:

>>> print urlresolvers.reverse('admin:myapp_mymodel_change', args=(obj.id,))
/admin/myapp/mymodel/123/

I have a generic foreign key on a model, and I'd like to provide a link in admin to the object's corresponding change page. Since it can be any type of model, I can't easily use reverse(). Is there some way I could simply this to the following?

>>> get_admin_change_url(obj)
/admin/myapp/mymodel/123/
Cerin
  • 60,957
  • 96
  • 316
  • 522

1 Answers1

5

Once you have the object, you can access its app label and name on its _meta class, then construct the name of the admin change url dynamically.

app_label = obj._meta.app_label
model = obj._meta.module_name

reverse('admin:%s_%s_change' % (app_label, model), args=(obj.id,))
Alasdair
  • 298,606
  • 55
  • 578
  • 516
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • 2
    Note, this assumes your admin.py matches your models.py, which is usually will. This won't work if you're using proxy model, or show a model's modeladmin under a different app_label. – Cerin Apr 15 '13 at 22:34
  • It will work fine if you use your proxy model as *the* model for the `ModelAdmin`. I'm not sure why you *wouldn't* do that, since you wouldn't really be working with the right thing at that point. – Chris Pratt Apr 15 '13 at 22:37
  • You would. I have a use case where I present different admin views depending on the context/user. One is based on the original model, the other on proxies for that model. – caram Feb 25 '21 at 11:29
  • Actually, `reverse()` does work for proxy models. If your proxy happens to live on a different site, you have to use that site prefix, e.g. `reverse('mysite:myapp_myproxy_changelist')`, where `mysite` is different from `admin`. – caram Feb 25 '21 at 11:37