0

I am trying to figure out how to do a simple export of data to a CSV file. I found an example that works....

def export_data(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="users.csv"'

    writer = csv.writer(response)
    writer.writerow(['username', 'First name', 'Last name', 'Email address'])

    users = User.objects.all().values_list('name','userid')
    for user in users:
    writer.writerow(user)

    return response

The code above works as you would expect, exporting all of the users from User.objects.all() to the spreadsheet. However, I am trying to do this from a DetailView and only get the data for the user that is being viewed, not the entire model, with the .all().

From what I gather, in order to do this in a DetailView, I believe I need to do something like...

class ExportDataDetailView(LoginRequiredMixin,DetailView):
    model = Author
    context_object_name = 'author_detail'

....And then perhaps I need to override get_queryset? It seems like overkill though because I'm already in the DetailView...

Thanks for any pointers in the right direction in advance.

Steve Smith
  • 1,019
  • 3
  • 16
  • 38

2 Answers2

2

When you are using DetailView, means you can use only object. If you want to export that, you can do the following:

class ExportDataDetailView(LoginRequiredMixin,DetailView):

    model = Author
    context_object_name = 'author_detail'

    def render_to_response(self, context, **response_kwargs):
        user = context.get('author_detail')  # getting User object from context using context_object_name
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="users.csv"'
        writer = csv.writer(response)
        writer.writerow(['username', 'First name', 'Last name', 'Email address'])
        writer.writerow([user.username, user.first_name, ...])
        return response

Now, if you want all users' data, then you can use ListView:

from django.views.generic.list import ListView

class ExportDataListView(LoginRequiredMixin,ListView):
    model = Author
    context_object_name = 'authors'

    def render_to_response(self, context, **response_kwargs):
        authors = context.get('authors')  # getting all author objects from context using context_object_name
        users = authors.values_list('name','userid', ...)
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="users.csv"'
        writer = csv.writer(response)
        writer.writerow(['username', 'First name', 'Last name', 'Email address'])
        for user in users:
           writer.writerow(user)
        return response
ruddra
  • 50,746
  • 7
  • 78
  • 101
  • How do do for a word document as well? I tried changing the type and the filename extension and got the document to open up but no data. I tried changing writer = doc.writer but that didn't work. Specifically for DetailView. – Steve Smith Feb 12 '19 at 14:59
  • Maybe this answer will help: https://stackoverflow.com/questions/23821352/generate-the-ms-word-document-in-django – ruddra Feb 12 '19 at 15:36
0

When you iterate over the queryset, you need to use:

for user in users:
   writer.writerow(user.username, user.first_name, user.last_name, user.email)
diek
  • 657
  • 7
  • 16
  • Thank you for the response. That’s not where I’m stuck . I’m trying to figure out how to get the attributes from the DetailView. I can’t figure out how to get only the record that is being displayed in my DetailView. If I’m not mistaken your suggestion would give me all of the users. I’m only trying to get the one on my DetailView exported to a CSV. – Steve Smith Feb 12 '19 at 01:40
  • You are correct, the fact that you asked for CSV does not make sense. Why would you need to generate a one record csv? – diek Feb 12 '19 at 02:55
  • If I have a record on a screen I want to be able to give the user the ability to export that data to an excel spreadsheet – Steve Smith Feb 12 '19 at 03:00