Bir csv dosyasını ek indirme olarak kaydetmeye çalışıyorum. CSV dosyalarının boyutu 4 MB veya daha fazla olacak ve kullanıcının, önce belleğe oluşturulacak ve belleğe yüklenecek tüm verileri beklemeden dosyaları etkin bir şekilde indirebilmesi için bir yola ihtiyacım var.Django'da bir CSV dosyası akışı
İlk olarak Django'nun FileWrapper
sınıfına dayanan kendi dosya sarıcımı kullandım. Bu başarısız oldu. Sonra tepkisini akışı için bir jeneratör kullanarak burada bir yöntem gördüm: Ben jeneratör içinde bir hata kaldırdıklarında How to stream an HttpResponse with Django
, ben get_row_data()
fonksiyonu ile uygun veri oluşturma görüyoruz, ama ben çalıştığınızda cevabı geri döndüğünde geri döner. Ayrıca Django GZipMiddleware
'u da devre dışı bıraktım. Yanlış yaptığımı bilen var mı?
Düzeltme: Sorun yaşıyorum ConditionalGetMiddleware
ile oldu. Onu değiştirmek zorundaydım, kod aşağıda bir cevapta. İşte
from django.views.decorators.http import condition @condition(etag_func=None) def csv_view(request, app_label, model_name): """ Based on the filters in the query, return a csv file for the given model """ #Get the model model = models.get_model(app_label, model_name) #if there are filters in the query if request.method == 'GET': #if the query is not empty if request.META['QUERY_STRING'] != None: keyword_arg_dict = {} for key, value in request.GET.items(): #get the query filters keyword_arg_dict[str(key)] = str(value) #generate a list of row objects, based on the filters objects_list = model.objects.filter(**keyword_arg_dict) else: #get all the model's objects objects_list = model.objects.all() else: #get all the model's objects objects_list = model.objects.all() #create the reponse object with a csv mimetype response = HttpResponse( stream_response_generator(model, objects_list), mimetype='text/plain', ) response['Content-Disposition'] = "attachment; filename=foo.csv" return response
Ben tepkisini akarsu kullanmak jeneratör: def get_row_data(model, row):
"""Get a row of csv data from an object"""
#Create a temporary csv handle
csv_handle = cStringIO.StringIO()
#create the csv output object
csv_output = csv.writer(csv_handle)
value_list = []
for field in model._meta.fields:
#if the field is a related field (ForeignKey, ManyToMany, OneToOne)
if isinstance(field, RelatedField):
#get the related model from the field object
related_model = field.rel.to
for key in row.__dict__.keys():
#find the field in the row that matches the related field
if key.startswith(field.name):
#Get the unicode version of the row in the related model, based on the id
try:
entry = related_model.objects.get(
id__exact=int(row.__dict__[key]),
)
except:
pass
else:
value = entry.__unicode__().encode("utf-8")
break
#if it isn't a related field
else:
#get the value of the field
if isinstance(row.__dict__[field.name], basestring):
value = row.__dict__[field.name].encode("utf-8")
else:
value = row.__dict__[field.name]
value_list.append(value)
#add the row of csv values to the csv file
csv_output.writerow(value_list)
#Return the string value of the csv output
return csv_handle.getvalue()
: Burada def stream_response_generator(model, objects_list):
"""Streaming function to return data iteratively """
for row_item in objects_list:
yield get_row_data(model, row_item)
time.sleep(1)
Ve csv satır veri oluşturmak nasıl olduğunu Burada
görünümüdür
Henüz veri akışı ihtiyacım olmadı, ancak basit ve zarif bir şey elde etmenin ne kadar hızlı olduğunu bilmek güzel. –
Bu cevabı gerçekten beğenmeme rağmen, bunun benim sorunum olmadığı ortaya çıkıyor. Tam olarak yazdığınız bu tam kodu kullandım, sadece bir yanıt üretip üretmeyeceğini görmek için, ancak yanıt 0 bayt olarak geri dönüyor. Yani hala aynı sonuca sıkıştım. – bfrederix
Bu kod düzgün çalışıyor, bu nedenle sorun gidermeniz gereken ortamınızla ilgili bir sorun var. –