[Fixed]-How to export Django model data into CSV file

31πŸ‘

βœ…

I usually prefer an action for this in the admin. This is the snippet:

def download_csv(modeladmin, request, queryset):
    if not request.user.is_staff:
        raise PermissionDenied
    opts = queryset.model._meta
    model = queryset.model
    response = HttpResponse(mimetype='text/csv')
    # force download.
    response['Content-Disposition'] = 'attachment;filename=export.csv'
    # the csv writer
    writer = csv.writer(response)
    field_names = [field.name for field in opts.fields]
    # Write a first row with header information
    writer.writerow(field_names)
    # Write data rows
    for obj in queryset:
        writer.writerow([getattr(obj, field) for field in field_names])
    return response
download_csv.short_description = "Download selected as csv"

To use it in your view function

def myview(request):
    data = download_csv(ModelAdmin, request, Model.objects.all())

    return HttpResponse (data, content_type='text/csv')
πŸ‘€symbiotech

11πŸ‘

Hi you can simply do it

views.py

from django.http import HttpResponse
import csv

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

    writer = csv.writer(response)
    writer.writerow(['employee','IG', 'follower', 'email', 'website', 'DA', 'youtube_url', 'youtube_name', 'subscriber', 'type','country'])

    users = Library.objects.all().values_list('employee','IG', 'follower', 'email', 'website', 'DA', 'youtube_url', 'youtube_name', 'subscriber', 'type','country')
    for user in users:
        writer.writerow(user)

    return response

urls.py

from .views import export_users_csv

path('export', export_users_csv, name='export_users_csv'),

page.html

<a href="{% url 'export_users_csv' %}">Export all users</a>
πŸ‘€mfathi

11πŸ‘

Here is an updated and version of @symbiotech answer for Python 3.
Inspired by this snippet and this article


utils.py

def download_csv(request, queryset):
  if not request.user.is_staff:
    raise PermissionDenied

  model = queryset.model
  model_fields = model._meta.fields + model._meta.many_to_many
  field_names = [field.name for field in model_fields]

  response = HttpResponse(content_type='text/csv')
  response['Content-Disposition'] = 'attachment; filename="export.csv"'

  # the csv writer
  writer = csv.writer(response, delimiter=";")
  # Write a first row with header information
  writer.writerow(field_names)
  # Write data rows
  for row in queryset:
      values = []
      for field in field_names:
          value = getattr(row, field)
          if callable(value):
              try:
                  value = value() or ''
              except:
                  value = 'Error retrieving value'
          if value is None:
              value = ''
          values.append(value)
      writer.writerow(values)
  return response

views.py

def export_csv(request):
  # Create the HttpResponse object with the appropriate CSV header.
  data = download_csv(request, Publication.objects.all())
  response = HttpResponse(data, content_type='text/csv')
  return response
πŸ‘€Antiez

0πŸ‘

Tweaked one line. To avoid returning AttributeError exceptions, you can add in a default value of None if the attribute doesn’t exist.

writer.writerow([getattr(obj, field, None) for field in field_names])

0πŸ‘

Another quick and simple approach is to use the pandas library.

import pandas as pd

...

def export_csv(request):
  df = pd.DataFrame(o.__dict__ for o in MyModel.objects.all())
  df.to_csv("/my/path/my_filename.csv")
  return HttpResponse("<p>Done!</p>")
    

Leave a comment