Package: django-csv-downloads
Django CSV DownloadsDjango app for tracking queryset-backed CSV downloadsVersion supportThe current version of the this app supportPython 3.8+andDjango
3.2+What does this app do?This app is used to track user downloads of CSVs that are derived from
Django QuerySets. You provide the filename, queryset and the list of
columns that you want to output.It has a single model (CsvDownload) that tracks downloads and stores
the user, filename, row count and timestamp.UsageThe recommended way to use this app is to rely ondjango_csv.views.download_csv, which wraps up the creation of the
download object and the generation of the CSV itself:# DISPLAY PURPOSES ONLY: DO NOT ENABLE USER DATA DOWNLOADS IN PRODUCTIONdefdownload_users(request:HttpRequest)->HttpResponse:data=User.objects.all()columns=("first_name","last_name","email")returndownload_csv(request.user,"users.csv",data,*columns)SettingsThere is aCSV_DOWNLOAD_MAX_ROWSsetting that is used to truncate
output. Defaults to 10000. This is a backstop, and can be overridden on
a per use basis.ExamplesCaution:All of these examples invåolve the User model as it's
ubiquitous - DO NOT DO THIS ON A PRODUCTION ENVIRONMENT.Example of writing a QuerySet to a file:>>>data=User.objects.all()>>>columns=("first_name","last_name","email")>>>withopen('users.csv','w')ascsvfile:>>>csv.write_csv(csvfile,data,*columns)10#<--- row countadding a custom header:>>>data=User.objects.all()>>>columns=("first_name","last_name","email")>>>column_headers=("given_name","family_name","email_address")>>>withopen('users.csv','w')ascsvfile:>>>csv.write_csv(csvfile,data,*columns,column_headers=column_headers)10Example of writing to an HttpResponse:>>>response=HttpResponse(content_type="text/csv")>>>response["Content-Disposition"]='attachment; filename="users.csv"'>>>csv.write_csv(response,data,*columns)10Example of writing to an in-memory text buffer:>>>buffer=io.StringIO()>>>csv.write_csv(buffer,data,*columns)10Example of writing directly to S3:>>>withs3.s3_upload("bucket_name","object_key")asbuffer:...csv.write_csv(fileobj,queryset,*columns)10>>># one-line convenience function>>>s3.write_csv_s3("bucket_name/object_key",queryset,*columns)10Example of writing directly to SFTP:# requires a paramiko.SFTPClient to have been created / connected.>>>withsft.sftp_upload(client,remote_filepath)asfileobj:...write_csv(fileobj,queryset,*columns)10>>># one-line convenience function>>>sftp.write_csv_sftp("sftp://user:pass@host:port/path",queryset,*columns)10Example of a custom admin action to download User data:classCustomUserAdmin(UserAdmin):actions=['download']csv_fields=("first_name","last_name","email","is_staff")csv_filename="users.csv"defdownload(self,request,queryset):"""Download selected users as a CSV."""returndownload_csv(user=request.user,filename=CustomUserAdmin.csv_filename,queryset=queryset,*CustomUserAdmin.csv_fields)download.short_description="Download selected users"Example CBV that restricts queryset based on request.user:classDownloadUsers(CsvDownloadView):defhas_permission(self,request:HttpRequest)->bool:returnrequest.user.is_authenticateddefget_queryset(self,request:HttpRequest)->QuerySetWriter:"""Allow superusers to download Users."""ifrequest.user.is_superuser:returnUser.objects.all().order_by("first_name","last_name")returnUser.objects.none()defget_filename(self,request:HttpRequest)->str:return"users.csv"defget_columns(self,request:HttpRequest)->str:return("first_name","last_name")