Django Admin Custom Download Button

Django Admin interface provides action buttons to work with multiple records. But in order to create a custom button in django admin per row/record we might need some help of JS. The aim here is to create a Download button for each row which when clicked will download a field of that record and save it to a csv file.

Let’s say our models is as follows:

class OurModel(models.Model):
    items = JSONField(null=True, blank=True)
    name = models.CharField(max_length=200)

The items is JSON field with the following data:
{1:’abc’,2:’def’}

In order to display our Download button we will need the help of admin.py and a .js file. On admin.py we define the admin class:

class OurModelAdmin(admin.ModelAdmin):
    list_display = ('item', 'name', 'download_content')
    class Media:
        js = ('admin/js/ourmodel.js',)
    def download_content(self, obj):
        return '<a href="#">Download</a>'
    download_content.allow_tags = True
    download_content.short_description = "Download Content File"

And within ourmodel.js file we define how the download button works:

var $ = django.jQuery;
$(document).ready(function() {
    $('.field-download_content').click('a', function() {
        var id = $(this).parent().children('.action-checkbox').children('.action-select').val().toString();
        var items = JSON.parse($(this).parent().children('.field-item').html());
        var keys = Object.keys(items);
        var A = [['id', 'string']];
        for (var j = 1; j < keys.length; ++j) {
            A.push([keys[j], '"'+items[keys[j]]+'"', '']);
        }
        var csvRows = [];
        for (var i = 0, l = A.length; i < l; ++i) {
            csvRows.push(A[i].join(','));
        }
        var csvString = csvRows.join("%0A");
        var a = document.createElement('a');
        a.href = 'data:text/csv;charset=utf-8,' + csvString;
        a.target = '_blank';
        a.download = 'ourfile_'+id+'.csv';
        document.body.appendChild(a);
        a.click();
    });
});
Advertisement