Django Hack: adding extra data to admin interface

A common need I have for Django’s admin interface is to show a little more data for convenience right on the edit page. For example showing a link to a foreign key’s edit page right there. The way I do this is by setting the help_text field in the render_change_form function. I create a new function in my admin class to override render_change_form

class whateverAdmin(admin.modelAdmin):
 def render_change_form(self, request, context, *args, **kwargs):
  context['adminform'].form.fields['someField'].help_text = "Go to edit page " + str(context['original'].anyFunction()) + " (will discard changes)"
  return super(whateverAdmin, self).render_change_form(request, context, args, kwargs)

the anyFunction() is just a function I made to display a URL in my model. Notice the allow_tags line to allow the function to return the html <a> tag

def anyFunction(self):
 try:
  field = self.someField
  urlRes = urlresolvers.reverse('admin:appName_someField_change', args=(field.id,))
  return '</a><a href="http://example.com' + urlRes + '">' + str(field) + '</a>'
 except:
 return ""
anyFunction.allow_tags = True

This link is then very convenient when using the admin interface just to look up information. The render_change_from function is also useful to editing about the admin page. I use it to modify queryset’s for foreign key data as well.

Comments

3 responses to “Django Hack: adding extra data to admin interface”

  1. Derek Avatar

    Can you explain some more how you “use it to modify queryset’s for foreign key data as well.”?

    Thanks!

    Like

  2. admin Avatar
    admin

    Derek, I sometimes modify the possible options on a foreign key’s dropdown box in the admin site. In my admin.py file I can add something like this

    def render_change_form(self, request, context, *args, **kwargs):
    compUsers = User.objects.filter(Q(groups__name=’company’))
    context[‘adminform’].form.fields[‘login’].queryset = compUsers

    Without this the ‘login’ foreign key field options were every user. Now it’s only users who are part of the group ‘company’

    Like

  3. Luke Plant Avatar

    This way of building up HTML in a function is insecure, and could easily open you up to XSS attacks (or anyone who copy-pastes this code). It would be far better to use format_html – https://docs.djangoproject.com/en/1.6/ref/utils/#django.utils.html.format_html

    Like

Leave a comment