Создание CSV-файла с помощью Django (динамическое содержимое)
внутри моего view.py, у меня есть две функции, одна из которых обрабатывает ввод из формы и выводит отфильтрованный список, а другая, которая должна экспортировать этот список в CSV.
вот возвращение моей первой функции:
return render_to_response('templateX.html',
{
'queryset': queryset,
'filter_form': filter_form,
'validated': validated,
},
context_instance = RequestContext(request)
)
вот функция экспорта:
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
Я не уверен, как получить объект QuerySet из моей первой функции, которая содержит список элементов, которые я хочу в моем CSV и использовать его в моей функции export_to_csv. Или лучший способ объединить эти две функции и заставить пользователя нажать на флажок, хочет ли он/она загрузить файл CSV. Любая помощь будет оценена.
4 ответов
Я бы рекомендовал объединить их в одну функцию просмотра, которая принимает дополнительный параметр:
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))
затем urls.py
, положите что-то вроде этого в свой urlpatterns
:
url(r'^form', 'my_view', {"exportCSV": False}, name="form"),
url(r'^csv', 'my_view', {"exportCSV": True}, name="export"),
IMHO, лучше всего было бы объединить их и генерировать данные CSV из явного набора запросов. Это может быть переписано на что-то общее, как(не проверено):
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
который вы можете использовать следующим образом:
def my_view(request):
calls = Call.objects.all()
return export_to_csv(request, calls, fields = ('calldate', 'src', 'dst'))
--
приведенный пример кода предполагает, что набор запросов задан в данных сеанса, что может вызвать множество ошибок, а также проблемы безопасности. Если вы храните сеансы в своей базе данных, вы можете в конечном итоге читать данные, просто чтобы запишите его обратно в гораздо менее эффективной форме.
Я нашел способ сделать это, который отличается от кнутина. Я объявил пустой список с именем csv_list = [] вне моих функций или глобальной переменной.
в моей основной функции (той, которая обрабатывает и фильтрует на основе пользовательского ввода) я делаю этот csv_list глобальным, чтобы он был установлен в "обновленную" версию queryset. Затем, чтобы создать csv, это так же просто, как: для вызова в csv_list: писатель.writerow([звонок.ГРЦ, звоните.летнее время]) ответ
Это теперь работает разумно.
следующее принимает в Django queryset и выплевывает CSV-файл.
использование::
из utils импортировать dump2csv
из dummy_app.импорт моделей *
qs = DummyModel.объекты.all ()
dump2csv.dump(qs,'./ данные / дамп.csv')
сценарий:
import csv
from django.db.models.loading import get_model
def dump(qs, outfile_path):
model = qs.model
writer = csv.writer(open(outfile_path, 'w'))
headers = []
for field in model._meta.fields:
headers.append(field.name)
writer.writerow(headers)
for obj in qs:
row = []
for field in headers:
val = getattr(obj, field)
if callable(val):
val = val()
if type(val) == unicode:
val = val.encode("utf-8")
row.append(val)
writer.writerow(row)