9👍
in your view
import csv
.....
output = []
response = HttpResponse (content_type='text/csv')
writer = csv.writer(response)
query_set = User.objects.select_related('profile').all()
#Header
writer.writerow(['First Name', 'Last Name', 'Full Name', 'Short Name'])
for user in query_set:
output.append([user.first_name, user.last_name, user.get_full_name, user.profile.short_name])
#CSV Data
writer.writerows(output)
return response
This works prefectly
4👍
If you are using classed based views, its really easy (this is the sort of task where they shine). Subclass the main view, override the template and content type.
Here is an example from one of my projects
views.py
class SavedSamplesView(ListView):
"""
This is the standard view returning HTML
"""
template_name = "SavedSamples.html"
model = Sample
context_object_name = "sample_list"
def get_queryset(self) :
slug = self.kwargs['submission_slug']
return Sample.objects.filter(submission__submission_slug=slug)
class SavedSamplesCsvView(SavedSamplesView):
"""
Subclass of above view, to produce a csv file
"""
template_name = 'SavedSamples.csv'
content_type = 'text/csv'
The template SavedSamples.cvs looks like this (the formatting to get the newline is a little ugly, but it works). The first line is the headers, remove that if you don’t need it:
sample.id , sample.name , ... , comments
{% for sample in sample_list %}{{ sample.id }},{{ sample.name }},....,{{sample.comments}}
{% endfor %}
urls.py
url(r'^savedsamplescsv/(?P<submission_slug>[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890\-_]+)/', views.SavedSamplesCsvView.as_view(), name='saved_samples_csv'),
I would use a link instead of a button, and style it as button.
- [Django]-Django: How to keep track of a linear (yet flexible) project management workflow?
- [Django]-Formatting Time Django Template
- [Django]-How can I know if a email is sent correctly with Django/Python?
- [Django]-Opening a new browser tab invalidates Django's CSRF token, preventing form submission
- [Django]-Where is Break button in Dell Inspiron 15R
3👍
I use the following snippet to generate a CSV for my queryset. It also includes related fields, that you can choose to ignore or use something else to serialize the data. ( Such as the default serializers that come with Django )
import csv
def dump_to_csv(model, qs):
"""
Takes in a Django queryset and spits out a CSV file.
"""
model = qs.model
writer = ''
headers = []
# Get standard fields
for field in model._meta.get_fields():
headers.append(field) if 'extra' not in field.name else None
writer += ','.join([field.name for field in headers])
writer += '\n'
for obj in qs:
row = []
for field in headers:
# Append all general fields
if field.get_internal_type() not in ['ForeignKey', 'ManyToManyField', 'OneToOneField']:
val = getattr(obj, field.name)
if callable(val):
val = val()
if type(val) == str:
val = val.encode("utf-8")
row.append(str(val))
# Append all fk fields
elif field.get_internal_type() in ['ForeignKey', 'OneToOneField']:
from django.core import serializers
import json
value = field.value_from_object(obj)
if value not in [None, ""]:
qs = field.remote_field.model.objects.filter(pk=value)
json_data = serializers.serialize("json", qs, fields=(field.name for field
in qs.first()._meta.get_fields() if
'extra' not in field.name))
json_data = [o['fields'] for o in json.loads(json_data)]
json_data = json.dumps(json_data)
json_data = json_data.replace(",", ";")
json_data = json_data.replace("\"", "'")
row.append(json_data)
else:
row.append("[]")
# Append all m2m fields
elif field.get_internal_type() in ['ManyToManyField']:
from django.core import serializers
import json
qs = getattr(obj, field.name).all()
json_data = serializers.serialize("json", qs)
json_data = [o['fields'] for o in json.loads(json_data)]
json_data = json.dumps(json_data)
json_data = json_data.replace(",", ";")
json_data = json_data.replace("\"", "'")
row.append(json_data)
writer += ','.join(row)
writer += '\n'
return writer
The reason I have this is because my use case requires me to have a JSON dump of each related object as well.
You can then return this in the response so:
file = dump_to_csv(qs.model, qs)
response = HttpResponse(file, content_type='text/csv')
response['Content-Disposition'] = u'attachment; filename="{0}"'.format('export.csv')
return response
0👍
Im late, but this could help someone…
In my case, i create a submit btn in my template to post something like this:
import pandas
[...]
if request.method == 'POST':
[...]
dataset = "ur query here"
response = HttpResponse (content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="file.csv"'
pandas.DataFrame(dataset).to_csv(response)
return response
- [Django]-Can't debug django app in VS Code with docker database: 'could not translate host name "db" to address: Name or service not known'
- [Django]-Using HttpResponseRedirect, but browser is not showing correct URL