简体   繁体   English

如何将JSON文件的内容放入响应中

[英]How to put a JSON file's content in a response

I have a file on my computer that I'm trying to serve up as JSON from a django view. 我的计算机上有一个文件,我正试图从django视图中提供JSON。

def serve(request):
    file = os.path.join(BASE_DIR, 'static', 'files', 'apple-app-site-association')
    response = HttpResponse(content=file)
    response['Content-Type'] = 'application/json'

What I get back is the path to the file when navigating to the URL 我得到的是导航到URL时文件的路径

/Users/myself/Developer/us/www/static/files/apple-app-site-association

What am I doing wrong here? 我在这做错了什么?

os.path.join returns a string, it's why you get a path in the content of the response. os.path.join返回一个字符串,这就是你在响应内容中获得路径的原因。 You need to read the file at that path first. 您需要先在该路径上读取文件。

For a static file 对于静态文件

If the file is static and on disk, you could just return it using the webserver and avoid using python and django at all. 如果文件是静态的并且在磁盘上,您可以使用Web服务器返回它,并且完全避免使用python和django。 If the file needs authenticating to be downloaded, you could still handle that with django, and return a X-Sendfile header (this is dependant on the webserver). 如果文件需要下载身份验证,您仍然可以使用django处理该文件,并返回X-Sendfile (这取决于Web服务器)。

Serving static files is a job for a webserver, Nginx and Apache are really good at this, while Python and Django are tools to handle application logic. 提供静态文件是Web服务器的工作,Nginx和Apache非常擅长这一点,而Python和Django是处理应用程序逻辑的工具。

Simplest way to read a file 读取文件的最简单方法

def serve(request):
    path = os.path.join(BASE_DIR, 'static', 'files', 'apple-app-site-association')
    with open(path , 'r') as myfile:
        data=myfile.read()
    response = HttpResponse(content=data)
    response['Content-Type'] = 'application/json'

This is inspired by How do I read a text file into a string variable in Python 这是受如何在Python中将文本文件读入字符串变量的启发

For a more advanced solution 获得更高级的解决方案

See dhke's answer on StreamingHttpResponse . 请参阅dhkeStreamingHttpResponse 的回答

Additional information 附加信息

If you feed HttpResponse a string a content you tell it to serve that string as HTTP body: 如果你喂HttpResponse字符串中的content ,你告诉它成为该字符串的HTTP主体:

content should be an iterator or a string. content应该是迭代器或字符串。 If it's an iterator, it should return strings, and those strings will be joined together to form the content of the response. 如果它是迭代器,它应该返回字符串,并且这些字符串将连接在一起以形成响应的内容。 If it is not an iterator or a string, it will be converted to a string when accessed. 如果它不是迭代器或字符串,则在访问时将转换为字符串。

Since you seem to be using your static storage directory, you might as well use staticfiles to handle content: 既然你似乎可以用你的静态存储目录,你还不如用staticfiles处理内容:

from django.contrib.staticfiles.storage import staticfiles_storage
from django.http.response import StreamingHttpResponse

file_path = os.path.join('files', 'apple-app-site-association')

response = StreamingHttpResponse(content=staticfiles_storage.open(file_path))
return response

As noted in @Emile Bergeron's answer , for static files, this should already be overkill, since those are supposed to be accessible from outside, anyway. 正如@Emile Bergeron的回答所指出的那样 ,对于静态文件,这应该已经过度,因为无论如何都应该可以从外部访问它们。 So a simple redirect to static(file_path) should do the trick, too (given your webserver is correctly configured). 因此,简单的重定向到static(file_path)应该可以解决问题(假设你的web服务器配置正确)。

To serve an arbitrary file: 要提供任意文件:

from django.contrib.staticfiles.storage import staticfiles_storage
from django.http.response import StreamingHttpResponse

file_path = ...

response = StreamingHttpResponse(content=open(file_path, 'rb'))
return response

Note that from Django 1.10 and on, the file handle will be closed automatically. 请注意,从Django 1.10开始,文件句柄将自动关闭。

Also, if the file is accessible from your webserver, consider using django-sendfile , so that the file's contents don't need to pass through Django at all. 此外,如果可以从您的Web服务器访问该文件,请考虑使用django-sendfile ,以便文件的内容根本不需要通过Django。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM