在Django服务器上以文本/纯文本格式提供原始文件
问题描述:
我有一个Django应用程序,用于上传KML文件以及中的state
值。要显示这些KML档案,我想访问他们的服务器上的原始文件,我正在尝试做如下:在Django服务器上以文本/纯文本格式提供原始文件
def result(request): #mapped to /getFiles url
state = request.GET['state']
res = KmlModel.objects.get(state__state__exact=state)
obj = res.Kml_File.url
serve_file(obj)
def serve_file(filename):
response = HttpResponse(mimetype="text/plain")
for line in open(filename):
response.write(line)
return response
我面临的问题是,上试图访问/getFiles?state=SomeState
,它给此错误 OSError at /getFiles [Errno 22] Invalid argument: 'http://127.0.0.1:8000/static/img/dynamic/RR.kml'
其中RR.kml
是SomeState
的匹配KML文件。
任何想法如何我可以解决这个问题?
编辑
def result(request):
state = request.GET['state']
res = KmlModel.objects.get(state__state__exact=state)
return HttpResponse(res.Kml_File.open(), mimetype='text/plain')
Models.py
class KmlModel(models.Model):
id = models.AutoField(primary_key=True)
Kml_File = models.FileField(upload_to='dynamic/')
state = models.ForeignKey(State)
def __unicode__(self):
return self.state.state
答
看来你存储这些KML文件的完整URL静态化,但随后你serve_file
方法你想像打开本地文件路径一样打开该URL,然后阅读并提供内容。
与其试图解决这个问题,为什么不重定向到静态URL?
res = KmlModel.objects.get(state__state__exact=state)
return HttpResponseRedirect(res.KML_File.url)
编辑其实,我知道你的KML_File
场大概是一个models.FileField。在这种情况下,您可以直接使用res.KML.File.open()
打开它,因此不需要将URL传递到serve_file方法。
另外,不要忘记你需要返回调用serve_file的结果。
答
是open()
标准Python open()
?如果是这样,这对文件进行操作,而不是URL(尽管在打开URL为open()
时我无法获得相同的例外)。尝试改为:
import urllib2
def serve_file(url):
response = HttpResponse(mimetype="text/plain")
for line in urllib2.urlopen(url):
response.write(line)
return response
您也可以尝试重定向到URL,但是,我不知道正确的MIME类型将为Content-type
响应报头中设置。
由于某种原因,仍会下载该文件。我添加了'content-type ='text/plain''来回应。 – Newtt 2014-10-09 12:17:58
好吧,现在我明白你在做什么。问题是,dev服务器将使用Python标准库中的'mimetypes'模块来猜测文件的类型,并且没有简单的方法来覆盖它。但是,当您转到生产环境时,您将能够明确地配置Web服务器以将“.kml”作为文本/纯文本进行处理。 – 2014-10-09 12:31:02
现在我看到有一个更简单的方法,请参阅我的编辑。 – 2014-10-09 12:45:19