在本文中,我们将给您介绍关于在Django中流式传输CSV文件的详细内容,并且为您解答django视频流传输的相关问题,此外,我们还将为您提供关于c#–如何在asp.net中流式传输视频内容?、Dja
在本文中,我们将给您介绍关于在Django中流式传输CSV文件的详细内容,并且为您解答django视频流传输的相关问题,此外,我们还将为您提供关于c# – 如何在asp.net中流式传输视频内容?、Django 流式响应中文csv样例、django 生成和下载CSV文件、Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField?的知识。
本文目录一览:- 在Django中流式传输CSV文件(django视频流传输)
- c# – 如何在asp.net中流式传输视频内容?
- Django 流式响应中文csv样例
- django 生成和下载CSV文件
- Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField?
在Django中流式传输CSV文件(django视频流传输)
我正在尝试将csv文件作为附件下载流式传输。CSV文件的大小已达到4MB或更大,我需要一种让用户主动下载文件的方法,而不必等待所有数据都先创建并提交到内存中。
我首先使用了我自己的基于DjangoFileWrapper
类的文件包装器。那失败了。然后,我在这里看到了一种使用生成器流式传输响应的方法:
如何使用Django流式传输HttpResponse
当我在生成器中引发错误时,可以看到我正在使用该get_row_data()
函数创建正确的数据,但是当我尝试返回响应时,它返回为空。我也禁用了DjangoGZipMiddleware
。有人知道我在做什么错吗?
编辑:我遇到的问题与ConditionalGetMiddleware
。我必须替换它,代码在下面的答案中。
这是视图:
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
这是我用来流式传输响应的生成器:
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)
这是我创建csv行数据的方法:
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()
答案1
小编典典这是一些简单的代码,将流式传输CSV;您可能可以从这里转到您需要做的一切:
import cStringIO as StringIOimport csvdef csv(request): def data(): for i in xrange(10): csvfile = StringIO.StringIO() csvwriter = csv.writer(csvfile) csvwriter.writerow([i,"a","b","c"]) yield csvfile.getvalue() response = HttpResponse(data(), mimetype="text/csv") response["Content-Disposition"] = "attachment; filename=test.csv" return response
这只是将每一行写入内存文件中,读取并产生该行。
此版本对于生成批量数据更有效,但是在使用它之前请务必了解以上内容:
import cStringIO as StringIOimport csvdef csv(request): csvfile = StringIO.StringIO() csvwriter = csv.writer(csvfile) def read_and_flush(): csvfile.seek(0) data = csvfile.read() csvfile.seek(0) csvfile.truncate() return data def data(): for i in xrange(10): csvwriter.writerow([i,"a","b","c"]) data = read_and_flush() yield data response = HttpResponse(data(), mimetype="text/csv") response["Content-Disposition"] = "attachment; filename=test.csv" return response
c# – 如何在asp.net中流式传输视频内容?
WebRequest wreq = (HttpWebRequest)WebRequest.Create(url); using (HttpWebResponse wresp = (HttpWebResponse)wreq.GetResponse()) using (Stream mystream = wresp.GetResponseStream()) { using (BinaryReader reader = new BinaryReader(mystream)) { int length = Convert.ToInt32(wresp.ContentLength); byte[] buffer = new byte[length]; buffer = reader.ReadBytes(length); Response.Clear(); Response.Buffer = false; Response.ContentType = "video/mp4"; //Response.BinaryWrite(buffer); Response.OutputStream.Write(buffer,buffer.Length); Response.End(); } }
但问题是整个文件在播放之前下载.如何让它流式传输和播放,因为它仍在下载?还是由客户/接收者应用来管理?
解决方法
您应该在while循环中读入较小的缓冲区.
例如:
byte[] buffer = new byte[4096]; while(true) { int bytesRead = myStream.Read(buffer,buffer.Length); if (bytesRead == 0) break; Response.OutputStream.Write(buffer,bytesRead); }
Django 流式响应中文csv样例
在Django里,流式响应StreamingHttpResponse
是个好东西,可以快速、节省内存地产生一个大型文件。
目前项目里用于流式响应的一个是Eventsource
,用于改善跨系统通讯时用户产生的慢速的感觉。这个不细说了。
还有一个就是生成一个大的csv文件。
当Django进程处于gunicorn或者uwsgi等web容器中时,如果响应超过一定时间没有返回,就会被web容器终止掉,虽然我们可以通过加长web容器的超时时间来绕过这个问题,但是毕竟还是治标不治本。要根本上解决这个问题,Python的生成器、Django框架提供的StreamingHttpResponse
这个流式响应很有帮助
而在csv中,中文的处理也至关重要,要保证用excel打开csv不乱码什么的。。为了节约空间,我就把所有代码贴到一起了。。实际使用按照项目的规划放置哈
上代码:
python
from __future__ import absolute_import import csv import codecs import cStringIO class Echo(object): def write(self, value): return value class UnicodeWriter: """ A CSV writer which will write rows to CSV file "f", which is encoded in the given encoding. """ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): # Redirect output to a queue self.queue = cStringIO.StringIO() self.writer = csv.writer(self.queue, dialect=dialect, **kwds) self.stream = f self.encoder = codecs.getincrementalencoder(encoding)() def writerow(self, row): self.writer.writerow([handle_column(s) for s in row]) # Fetch UTF-8 output from the queue ... data = self.queue.getvalue() data = data.decode("utf-8") # ... and reencode it into the target encoding data = self.encoder.encode(data) # write to the target stream value = self.stream.write(data) # empty queue self.queue.truncate(0) return value def writerows(self, rows): for row in rows: self.writerow(row) from django.views.generic import View from django.http.response import StreamingHttpResponse class ExampleView(View): headers=[''一些'',''表头''] def get(self,request): result = [[''第一行'',''数据1''], [''第二行'',''数据2'']] echoer = Echo() writer = UnicodeWriter(echoer) def csv_itertor(): yield codecs.BOM_UTF8 yield writer.writerow(self.headers) for column in result: yield writer.writerow(column) response = StreamingHttpResponse( (row for row in csv_itertor()), content_type="text/csv;charset=utf-8") response[''Content-Disposition'' ] = ''attachment;filename="example.csv"'' return response
django 生成和下载CSV文件
一、生成小型的csv文件
1、直接处理数据
from django.http import HttpResponse
import csv
# 简单生成下载csv文件
def down_csv_1(request):
# 指定返回的类型为csv
response = HttpResponse(content_type=''text/csv'')
# 添加返回头说明如何处理这个返回对象,并指明文件名。attachment:作为附件的形式进行下载
response[''Content-Disposition''] = "attachment;filename=''test.csv''"
# 创建写的对象
writer = csv.writer(response)
# 写入一行数据
writer.writerrow([''username'',''age''])
# 写入下一行数据
writer.writerrow([''Xsan'',20])
return response
2、使用模版处理要下载的数据:
(1)在templates文件夹下面创建处理数据的模版文件比如test.txt。
test.txt文件
{# 一定要将循环体和for语句写在一行,否则会出现空行的情况 #}
{% for row in rows %}{{ row.0 }},{{ row.1 }}
{% endfor %}
(2)在视图函数中引用
views.py
from django.http import HttpResponse
from django.template import loader
import csv
#使用模版处理要下载的数据
def down_csv_2(request):
# 指定返回的类型为csv
response = HttpResponse(content_type=''text/csv'')
# 添加返回头说明如何处理这个返回对象,并指明文件名。attachment:作为附件的形式进行下载
response[''Content-Disposition''] = "attachment;filename=''test.csv''"
# 创建要下载的数据,此时要和模版结合起来
context = {
''rows'':[
[''username'',''age''],
[''Xsan'',20]]
}
# 引用自定义的模版
template = loader.get_template(''test.txt'')
# 将要下载的数据使用模版格式化
csv_template = template.render(context)
# 将处理好的数据渲染至上下文
response.content = csv_template
return response
二、生成大型的csv文件
上面我们讲了生成一个小的csv文件,如果要生成大型的csv文件该如何做呢?上面的代码可能会发生超时的情况(服务器要生成一个大型的csv文件,需要的时间可能会超过浏览器默认的时间)。这时候我们需要借助一个类StreamingHttpResponse对象,这个对象能将响应的数据作为一个流返回给客户端,而不是作为一个整体返回。
关于StreamingHttpResponse:
这个类时专门用来处理流数据的。使得在处理大型文件的时候,不会因为服务器处理时间过长而导致连接超时。这个类不是继承自HttpResponse,并且跟HttpResponse对比有以下几点区别:
1、这个类没有属性content,相反是streaming_content。
2、这个类的streaming_content必须是一个可迭代对象。
3、这个类没有write方法,如果给这个类的对象写入数据将会报错。
注意:StreamingHttpResponse会启动一个进程来和客户端保持长连接,所以会很消耗资源。所以如果不是特殊要求,尽量少用这种方法。
views.py
from django.http import HttpResponse,StreamingHttpResponse
from django.template import loader
import csv
def large_csv_view(request):
response = StreamingHttpResponse(content_type=''text/csv'')
response[''Content-Disposition''] = "attachment;filename=''large.csv''"
rows = ("Row {},{}\n".format(row,row) for row in range(0,10000))
response.streaming_content = ("username,age\n","Xsan,20\n")
return response
Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField?
如何解决Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField??
大家。希望你做得很好。我想通过预先说明我是 AWS 的真正新手来开始这个问题。现在,我正在与一位已经拥有更多 Web 开发经验的朋友一起开发 Django 应用程序,他已经在 AWS 中设置了所有内容,也就是说,我们已将大部分文件上传到那里,正在运行一个暂存应用程序和其他一些配置。
我正在研究将一些数据库数据从我们的网络应用程序转换为 CSV 文件并将其上传到云端的后端实现。
基本上,我们有一个端点,用户可以在其中从站点的另一个 URL 请求数据,我们的应用程序会将数据转换为 .CSV 文件,将其导出到 S3 并同时 strong> 将其保存在模型的 FileField
上。然后,一旦文件被上传,用户将在其电子邮件中收到它。由于文件可能非常大,因此最大的问题是:如何将 .CSV 文件流式传输到 S3 Bucket 并让 Django 将其保存到模型的 FileField 属性中?这是我的参考代码(这是迄今为止在本地创建 .csv 的唯一方法):
--------------------------/// MODEL // ---------------------------------------------
class Export(models.ModelModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,)
file = models.FileField(upload_to=''s3://buckect/uploads/'',blank=True,null=True)
# Some other fields that don''t matter
-----------------------------///-EXPORT FUNCTION -----------------------------------
from io import StringIO
import csv
from smart_open import open
with open(''s3://buckect/uploads/test.csv'',''a+'') as fout:
csv_buffer = StringIO()
csv_writer = csv.writer(csv_buffer,escapechar='' '',quoting=csv.QUOTE_NONE)
data = data_generator(export_object.id)
for row in data:
csv_writer.writerow([row])
csv_file = csv_buffer.getvalue()
fout.write(csv_file)
export_object.file.save(''s3://buckect/test.csv'',fout)
我还没有测试它,因为我仍然无法访问 S3,但这在我看来是因为它会将文件上传到 S3 两次,不是吗?
我确实在本地尝试过,是的,确实在 open()
创建了 .CSV 文件并保存在模型中。但基于我对 S3 的有限了解,当您将其设置为存储时,我不太确定 Django 的 FileField
的行为如何。
另外,有人告诉我使用 Smart_open,据说它可以将我的文件流式传输到 S3。但我只发现 one similar usecase 并没有真正解释它是否或如何流式传输文件,而且它也是一个非常老的帖子。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
今天的关于在Django中流式传输CSV文件和django视频流传输的分享已经结束,谢谢您的关注,如果想了解更多关于c# – 如何在asp.net中流式传输视频内容?、Django 流式响应中文csv样例、django 生成和下载CSV文件、Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField?的相关知识,请在本站进行查询。
本文标签: