Pyramid渲染的JSON响应作为字符串返回

1 投票
1 回答
1547 浏览
提问于 2025-04-18 10:40

我正在使用Pyramid这个网页框架,写一些接收和返回JSON格式数据的函数。

下面是我写的一段代码,它可以返回指定目录下的文件和文件夹。

@view_config(route_name='file', renderer='json')
def file(request):
    values = request.json_body
    path = os.path.dirname(__file__) + '/files' + values['path']
    if os.path.isdir(path):
        files = [ f for f in os.listdir(path) if os.path.isfile(os.path.join(path,f)) ]
        dirs = [ f for f in os.listdir(path) if os.path.isdir(os.path.join(path,f)) ]
        if files is None:
            files = []
        if dirs is None:
            dirs = []
        response = dict()
        response['version']='1.0'
        response['files']=files
        response['directories']=dirs
        return response
    else:
        response = dict()
        response['version']='1.0'
        response['files']=[]
        response['directories']=[]
        return response

@view_config(route_name='files', renderer='templates/filesTest.jinja2')
def files(request):
    if 'form.submitted' in request.params:
        json_payload = json.dumps({'path':request.params['path']})
        headers = {'Content-Type':'application/json; charset=utf-8'}
        req = urllib2.Request(request.route_url('file'), json_payload, headers)
        resp = urllib2.urlopen(req)
        data = resp.read()
        return dict(dirs=[], files=[], saveURL = request.route_url('files'), pathDefault=request.params['path'])
    return dict(dirs=[], files=[], saveURL = request.route_url('files'), pathDefault='/')

我主要在处理文件功能时遇到问题。type(data)返回的是<type 'str'>。把这个字符串发送到我的模板时,显示的内容是{"files": ["file1.jpg", "file2.png"], "version": "1.0", "directories": ["Directory1"]}

有没有人知道我为什么会得到一个字符串的结果呢?

1 个回答

1

当你向服务器发出请求时,服务器会返回一些字节。你如何理解这些字节就看你自己了。如果你请求的是XML格式而不是JSON格式,你得到的也不是一个XML对象,而是可以被理解为XML的字节。

明确地发出请求其实是多余的。这在以下情况下是有道理的:

  • 跨语言使用
  • 跨组件使用,并且你希望它们之间的耦合度很低

在这种情况下,所有代码都在同一个组件里,并且使用的是同一种语言。一个更好的解决方案是使用一个辅助函数:

def fetch_files_and_directories(path):
    path = os.path.dirname(__file__) + '/files' + path
    if os.path.isdir(path):
        files = [ f for f in os.listdir(path) if os.path.isfile(os.path.join(path,f)) ]
        dirs = [ f for f in os.listdir(path) if os.path.isdir(os.path.join(path,f)) ]
        # Note that the is None check is nonsense.
        # The result of an empty list comprehension is an empty list, not None
    else:
        files = []
        directories = []
    return dict(directories=dirs, files=files)

@view_config(route_name='file', renderer='json')
def file(request):
    response = fetch_files_and_directories(request.json_body['path'])
    # you might want to move this into the fetch_* function.
    response['version']='1.0'
    return response

@view_config(route_name='files', renderer='templates/filesTest.jinja2')
def files(request):
    if 'form.submitted' in request.params:
        path = request.params['path']
        data = fetch_files_and_directories(path)
        # You did not use data below here, so neither did I.
        return dict(dirs=[], files=[], saveURL = request.route_url('files'), pathDefault=path)
    return dict(dirs=[], files=[], saveURL = request.route_url('files'), pathDefault='/')

请记住,file(request) 现在可能已经不再适用了。

撰写回答