Login

Admin list_display Ajax

Author:
whiteinge
Posted:
January 29, 2008
Language:
JavaScript
Version:
Not specified
Score:
7 (after 7 ratings)

Sometimes it can be time consuming to go through a bunch of objects in Django's Admin if you only need to update one field in each. An example of this is an order field that allows you to manually set the order for a queryset.

This snippet contains examples of how to set up the Admin list_display to make Ajax calls to a custom view.

The following code may not be worthy of being a snippet, it's all pretty straightforward, but here it is for those who just want to copy-and-paste.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
Sometimes it can be time consuming to go through a bunch of objects in Django's
Admin if you only need to update one field in each. An example of this is an
`order` field that allows you to manually set the order for a queryset.

This snippet contains examples of how to set up the Admin list_display to
make Ajax calls to a custom view (uses jQuery).

The following code may not be worthy of being a snippet, it's all pretty
straightforward, but here it is for those who just want to copy-and-paste.

Here is an example of the order field mentioned above::

    order = models.IntegerField(
        blank=True, null=True,
        help_text="""This field determines the order that products appear on
        the site. Enter any number, it does not matter what the number is, only
        that it is sequential compared to other products on the site. It is
        recommened that you use large numbers such as 100 and 200 to allow room
        for additional products or easy reordering in the future."""
        )

In your `models.py` add the following `order_helper` method to your
`list_display` [1]_. This will make <input> elements show up::

    def order_helper(self):
        return u'''<input type="text" name="%s" value="%s" size="3"
                class="order-helper">''' % (self.id, self.order)
    order_helper.allow_tags = True

.. [1] http://www.djangoproject.com/documentation/model-api/#list-display

Put the following jQuery somewhere that gets executed. This will color the
input boxes if the change succeeded or failed::
*/

    $(document).ready(function() {
        $('.order-helper').css("margin", "0");
        $('.order-helper').blur(function(){
            var input = $(this);
            $.ajax({
                url: "./"+ input.attr('name') +"/order/",
                data: order=input.attr('value'),
                type: "POST",
                complete: function(xhr_obj, msg){
                    if (msg == 'success') {
                        input.css("border", "1px solid green");
                    } else {
                        input.css("border", "1px solid red");
                    }
                },
            });

        });
    });

/*
Make a custom view somewhere to recieve the Ajax POST::

    @login_required
    @require_POST
    def order_helper(request, prod_id):
        prod = get_object_or_404(Product, id=prod_id)
        prod.order = request.POST.get('order')
        prod.save()
        return HttpResponse(content='Ok', status=200)

In your `urls.py` add a call to your new view. (If you use the same /admin/...
URL scheme as this example does, it must be *above* your regular Admin URLconf
include statement.)::

    url(r'^admin/products/product/(?P<prod_id>\d+)/order/$',
        'path.to.order_helper'),
*/

More like this

  1. Django Collapsed Stacked Inlines by applecat 1 year, 1 month ago
  2. Django Collapsed Stacked Inlines by mkarajohn 3 years, 3 months ago
  3. Dynamically adding forms to a formset. OOP version. by halfnibble 8 years, 11 months ago
  4. Convert multiple select for m2m to multiple checkboxes in django admin form by abidibo 11 years ago
  5. Django admin inline ordering - javascript only implementation by ojhilt 11 years, 4 months ago

Comments

andybak (on April 16, 2008):

Quick update on previous post. The problem with newforms-admin was down to me incorrectly setting my i_am_an_idiot property ;-)

You do however have to use mark_safe() as well as allow_tags. i.e.

from django.utils.safestring import mark_safe ... def order_helper(self): return mark_safe(u'''...etc...etc...''')

Probably a nice idea to set the following two as well:

order_helper.admin_order_field = 'order'
order_helper.short_description = 'Order'

#

andybak (on July 3, 2008):

Should line 43 be something like:

data: "order="+input.attr('value'),

#

Please login first before commenting.