Customizing Django Admin with jQuery? Getting '$ is not a function'?
Posted by Gene at 12:05 on Wed 5 May 2010 -- 3 Comments

Overview

When customizing the Django Admin, for example a change_list.html template, you might want to add some JavaScript of your own. If you just chuck in your jQuery code, using the $ alias, to the {% block extrahead %} you'll probably see $ is not a function in your browser's Error Console.

If you just intend to use the jQuery that the admin is loading, you'll find it is loaded in the {{block.super}} line below. But, Django also clears the $ alias to jQuery when loading and sets up the only jQuery alias to django.jQuery.

Reclaiming the $ alias

Consider this block of code


{% block extrahead %}

{{ block.super }}

<script type="text/javascript">
 function setClickEvents() {
  $('a').click(function(event) {
   alert('Clicked');
  });

 $(function() {
  setClickEvents();
 });
{% endblock %}

This will result in $ is not a function on a page reload. Add the line
var $ = django.jQuery to bring it back.


{% block extrahead %}

{{ block.super }}
<script type="text/javascript">
 function setClickEvents() {
  $('a').click(function(event) {
   alert('Clicked');
  });

  var $ = django.jQuery;
  $(function() {
   setClickEvents();
  });
{% endblock %}

Final thoughts

This works for me, but I can imagine there might be a case when you don't want to redfine $ like this. Afterall, Django is clearing it for a reason. This is alternative solution.

(function($) {
 $(document).ready(function($) {
  setClickEvents();
 });
})(django.jQuery);
Tags -
  • I'd like to add that some external plugins are already wrapping their code into an anonymous function, which, rather than "$", assumes "jQuery" to be available.

    In that case you have to define "var jQuery = django.jQuery;" in a script block that precedes the external reference to that file.

    Just found that out a minute ago :-)
    http://stackoverflow.com/questions/5484547/how-to-provide-to-third-party-external-jquery-plugins-in-django-admin

    - Danny Adair
  • What I've seen around about Django redefining $ is that it does to prevent conflicts with prototype. Cause prototype also uses $(). ;)

    - Jayme
  • Thank You!!
    It helped so much!
    I was stock for hours trying to figure out why $ can't work!!

    Many Thanks Again.

    - R
Subclassing User to add extra fields in the Django Admin Site
Posted by Gene at 11:04 on Wed 14 Apr 2010 -- 2 Comments

Overview

Do you have a Django application that uses the Admin Site and you would like to add custom fields to the User object? Below I discuss a object oriented way of implementing this.

Explanation

Subclass User in models.py.

from django.contrib.auth.models import User
class MyUser(User):
    bio=models.TextField(null=True,blank=True)
    clubs=models.ManyToManyField(Club,null=True,blank=True)

This allows us a place to add custom fields. For example, I've added a bio TextField and a relationship to a Club model object (not shown) to record the clubs to which the user belongs. For More information consider this explanation from scottbarnham.com

Subclass UserAdmin in your admin.py file.

from django.contrib.auth.admin import UserAdmin
class MyUserAdmin(UserAdmin):
  def __init__(self,*args,**kwargs):
    super(MyUserAdmin,self).__init__(*args,**kwargs)
    fields = list(UserAdmin.fieldsets[0][1]['fields'])
    fields.append('bio')
    fields.append('clubs')
    UserAdmin.fieldsets[0][1]['fields']=fields

admin.site.unregister(User)
admin.site.register(MyUser,MyUserAdmin)

This subclass allows us a way to add our fields to the standard fieldsets in UserAdmin. After coding this, and updating your database, load up your Django Admin, and have a look. Because MyUser does everything that User does, and more, we can register MyUser and unregister User.

Tags -
  • perfect.. thanks!

    - ark
  • nice...

    - Arsl