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();
});
});