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