开发者

Django admin Many2Many widget customization

I need to customize how the m2m widget for Django Admin gets displayed but I am kind of stumped where to start. 开发者_如何转开发I have tried subclassing couple of widgets from django.forms and django.contrib.admin.wigets but nothing seems to be working.

Here's a depiction of what I am looking for http://i.stack.imgur.com/81AY3.png.

Any help appreciated.


That looks like the kind of thing that could be achieved with JavaScript alone. For adding your own JavaScript to the Django admin, see the documentation for ModelAdmin media definitions.


This is what I came up with. It does most of the work. However, the list does not get updated when a new item is added and changing an item does not redirect back to the original page.

/your_app/forms.py

class ProductForm(forms.ModelForm):
    class Media:
        js = ('js/custom_m2m.js',)

    class Meta:
        model = Product

/your_media/js/custom_m2m.js

django.jQuery(function() {
    var $ = django.jQuery;

    // Add a new place holder div to hold the m2m list
    $('div.options div').append('<div class="newdiv"></div>');

    // Assign some variables
    var target = "options"; // <-- Target Field
    var newdiv = $('div.newdiv');
    var next_page = window.location.pathname;
    var add_link = $('div.'+target+' div a#add_id_'+target);
    var edit_img = "/static/media_admin/img/admin/icon_changelink.gif";
    var add_img = "/static/media_admin/img/admin/icon_addlink.gif";

    // Make the placeholder div bit nicer
    newdiv.attr("style", "line-height:20px; margin-left:105px;");

    // Iterate through select options and append them to 'newdiv'
    $('select#id_'+target+' option[selected="selected"]').each(function() {
        newdiv.append('<a href="/admin/shop/option/'+$(this).val()+'/?next='+next_page+'">'+$(this).text()+' <img src="'+edit_img+'" /></a><br />');
    });

    // Add a 'Add new' link after the option list
    add_link.html('<strong>Add new</strong> ' + add_link.html());
    add_link.appendTo(newdiv);

    // Show the 'newdiv' and hide the original dropdown
    $('select#id_'+target).after(newdiv);
    $('select#id_'+target).css("display", "none");
    $('div.'+target+' p[class="help"]').css("display", "none");
});

As you can see, the above script uses some hardcoded paths. Any improvement would be helpful.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜