Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating CSV file with Django (dynamic content)

Tags:

python

csv

django

Inside my view.py, I have two functions, one that processes input from a form and outputs a filtered list, and another that is supposed to export this list to CSV.

Here is the return of my first function:

return render_to_response('templateX.html',
{
 'queryset': queryset,
 'filter_form': filter_form,
 'validated': validated,
},
 context_instance = RequestContext(request)
 )

Here is the exporting function:

def export_to_csv(request):
    # get the response object, this can be used as a stream.
    response = HttpResponse(mimetype='text/csv')
    # force download.
    response['Content-Disposition'] = 'attachment;filename=export.csv'
    # the csv writer
    writer = csv.writer(response)
    qs = request.session['queryset']
    for cdr in qs:
        writer.writerow([cdr['calldate'], cdr['src'], cdr['dst'], ])
    return response   

I'm not sure how to get the queryset from my first function, which contains a list of the items I want in my CSV and use it in my export_to_csv function. Or would the best way be combining these two functions and have the user click on a checkbox whether he/she wants to download a CSV file. Any help would be appreciated.

like image 773
chiurox Avatar asked Nov 01 '10 19:11

chiurox


2 Answers

I'd recommend combining these into one view function which takes an extra parameter:

def my_view(request, exportCSV):
    # ... Figure out `queryset` here ...

    if exportCSV:
        response = HttpResponse(mimetype='text/csv')
        response['Content-Disposition'] = 'attachment;filename=export.csv'
        writer = csv.writer(response)
        for cdr in queryset:
            writer.writerow([cdr['calldate'], cdr['src'], cdr['dst'], ])
        return response
    else:
        return render_to_response('templateX.html', {'queryset': queryset,
            'filter_form': filter_form, 'validated': validated},
            context_instance = RequestContext(request))

Then, in your urls.py, put something like this in your urlpatterns:

url(r'^form', 'my_view', {"exportCSV": False}, name="form"),
url(r'^csv', 'my_view', {"exportCSV": True}, name="export"),
like image 65
Mike DeSimone Avatar answered Sep 18 '22 12:09

Mike DeSimone


IMHO, the best would be to combine them and generate the CSV data from an explicit queryset. This could then be rewritten to something general like(not tested):

def export_to_csv(request, queryset, fields):
    response = ...
    writer = csv.writer(response)
    for obj in queryset:
        writer.writerow([getattr(obj, f) for f in fields])
    return response

Which you can use like this:

def my_view(request):
    calls = Call.objects.all()
    return export_to_csv(request, calls, fields = ('calldate', 'src', 'dst'))

--

The example code you provided assumes the QuerySet is set in the session data, which could cause you tons of bugs as well as security problems. If you store sessions in your database, you could end up reading data, just to write it back in a much less efficient form.

like image 26
knutin Avatar answered Sep 20 '22 12:09

knutin