2016-11-17 74 views
0

我想在python中创建一个来自JSON API url的位置的HTML列表。但是,接受每一个元素,而不是在python中创建一个JSON url中的字典

@app.route('/api') 
def api(): 
url = urlopen('https://api.openaq.org/v1/locations?country=GB').read() 
#encoded we do not need it 
#encoded_data = json.dumps(url) 

#create variables 
array = [] 
data = {} 

#decoded 
decoded_data = json.loads(url) 

#we search for result each entry 
for i in decoded_data["results"]: 
    #append every entry to an array 
    array.append(i["location"]) 
#we create a dictionary from that array created which has a variable (for jinja2) called location 
data = [dict(location=array)] 
return render_template('api.html', data=data) 

,我得到这个:

[u'Aberdeen', u'Aberdeen Union Street Roadside', u'Aberdeen Wellington Road', u'Armagh Roadside', u'Aston Hill', u'Auchencorth Moss', u'Ballymena Ballykeel', u'Barnsley Gawber', u'Barnstaple A39', u'Bath Roadside', u'Belfast Centre', u"Belfast Stockman's Lane", u'Billingham', u'Birkenhead Borough Road', u'Birmingham A4540 Roads... 

编辑:模板

{% if data %} 
    <ul> 
    {% for d in data %} 
     <li>{{ d.location }}</li> 
    {% endfor %} 
    </ul> 
    {% else %} 
    <p class="lead"> 
     You should not see this msg, otherwise, check the code again. 
    </p> 
    {% endif %} 
+0

你能告诉我你是如何试图在模板中使用数据吗? – c3st7n

+0

我只是编辑它@ c3st7n –

回答

2

要转换的数组一个字典,但然后你把t他在一个长度为1的数组内填充字,唯一的对象是字典。问题是,你的模板然后期待数组中的每个元素都是一个字典,并带有一个“位置”字段。

你要么可以从转换data = dict(location=array)去掉方括号,然后更新您的模板,只是做for d in data.location,或者您可以更新追加通话追加而不是字符串的字典项:array.append({"location": i["location"]})

+0

它的工作原理!但只是第一个,我不能让它工作在第二个,非常感谢你! –

+0

第二个,你将只传入数组作为数据对象。该数组本质上是一个字典列表,所以模板会迭代每个字典,然后选择位置字段。 – louahola

0

试试这个:

import urllib.request, json 
    url = 'https://api.openaq.org/v1/locations?country=GB' 
    response = urllib.request.urlopen(url); 
    decoded_data = json.loads(response.read().decode("utf-8")) 
3

我打破了我回答了一下,因为我不想激活烧瓶。

import requests 

def api(): 
    res = requests.get('https://api.openaq.org/v1/locations?country=GB') 
    data = res.json()['results'] 
    return data 


@app.route('/api') 
def api(): 
    res = requests.get('https://api.openaq.org/v1/locations?country=GB') 
    try: 
     data = res.json()['results'] 
    except KeyError: 
     data = None 
    # this is the logic that you use in your template, I moved it out here 
    # cause i don't want to start a flask instance 
    for d in data: 
     print d['location'] 
    return render_template('api.html', data=data) 

api() 

基本上我使用可以返回json的请求模块。我将结果传递给数据变量。我用了一个for循环来演示它如何在你的模板中工作。基本上通过迭代d['location']

传中的数据作为一个字典,并获得位置因此,代码使用是

import requests 

@app.route('/api') 
def api(): 
    res = requests.get('https://api.openaq.org/v1/locations?country=GB') 
    try: 
     data = res.json()['results'] 
    except KeyError: 
     data = None 
    return render_template('api.html', data=data) 
+0

我也会尝试这个选项,但它的理解更复杂 –

+0

@AdriánVázquez我不明白它的复杂程度。它使用较少的行数,然后使用您的示例,减少对话和零列表构建。我将更新我的示例,仅包含准备好复制和粘贴的代码。 – reticentroot

1

几件事情:

  1. url是一个字节对象,该对象将无法使用json.loads(str)。因此,您必须通过执行json.loads(str(url,'utf-8'))或@Mattia建议的方法将它转换为字符串。

  2. @ louhoula是正确的。但是,如果你期待data是每个包含location键(这是想法,我先来看看你的模板),那么你应该在你的模板改变d.location词典列表:

    {% if 'location' in d.keys(): %}

    {{ d['location'] }} 
    

    {% else %} <p class="lead"> You should not see this msg, otherwise, check the code again. </p>

    {% endif %}