Subbu
Subbu

Reputation: 618

DJango - Export Json Field in Model to CSV along with other fields

I am working on a DJango project, and in the admin I need to add an action which will export and download the contents of the model. I have successfully added the export action using import-export and it downloads the data just fine.

Currently I just subclass using

ImportExportActionModelAdmin

and it automatically shows the export option in the drop down menu.

But now the issue is, one of the fields in the model being downloaded is a JSON field and gets exported to csv as JSON itself, rightly so. I want ideas on how can i convert this JSON field into csv as well.

Sample data that gets downloaded in the CSV:

{u'course_name': u'ABC', u'notes': u'Test', u'contact_mode': u'Message', u'contact_no': u'9876543210', u'stud_count': u'600', u'date': u'2018-12-19T18:30:00.000Z', u'email': u'[email protected]', u'exp11': u'YES'}

I did some reading and seems

import_export.widgets.JSONWidget 

can do the trick but am not sure how to implement this. Can some one give an example?

My Class that needs to be exported into CSV:

class Register(TimeStampedModel):
    email = models.EmailField(max_length=100)
    name = models.CharField(max_length=255)
    details = JSONField(null=True, blank=True, default={})

    def __str__(self):
        return '%s (%s)' % (self.name, self.email)

Thanks in advance.

Upvotes: 1

Views: 2092

Answers (1)

Subbu
Subbu

Reputation: 618

I solved the issue, and here is how I did it for anyone who might need it.

First import the following,

from django.db import models
from django.http import HttpResponse
from django.contrib import admin
from import_export.admin import ImportExportMixin
import json
import csv 

Then subclass your model admin using ImportExportMixin and ModelAdmin and then add the required action as shown below.

class PostAdmin(ImportExportMixin, admin.ModelAdmin):
    actions = [export_json_field,]

Now, define the function to be called when the user selects this action on the admin page of the model

def export_json_field(modeladmin, request, queryset):
    '''
    Exports the JSON fields in a model to csv file
    '''        
    #Create the httpResponse object with correct csv header
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="Json2Csv.csv"'
    writer = csv.writer(response)    
    count = 0
    # print(json.dumps(queryset[0].details))    
    for obj in queryset:                   
        #loop through all the fields in the current post object
        for field in obj._meta.fields:
            #find the fields with JSONField type
            if obj._meta.get_field(field.name).get_internal_type() == 'JSONField':
                #get the contents of the json field and convert it into json format
                detail = json.dumps(getattr(obj,field.name))
                #detail = "'" + detail + "'"
                detail_parsed = json.loads(str(detail))               
                #lists to store the keys and values from the json
                keys = []
                values = []
                #loop through each json row and make a list of the keys and values
                for key, value in detail_parsed.items():
                    keys.append(key)
                    values.append(value)    
                # write the values into csv file 
                # keys form the column headers so write them only once
                if count == 0:
                    writer.writerow(keys)
                    count += 1                
                # write the values in each row
                writer.writerow(values)                
    return response

export_json_field.short_description = 'Export Json TO Csv'

The last line gives a name to this action that is displayed in the dropdown box in the admin page (Export Json TO Csv)

Finally, register the model admin

admin.site.register(Post, PostAdmin)

This will let you use the importexport functionality of the django-import-export library as well as define your own action within the same admin page.

Hope it helps.

Upvotes: 1

Related Questions