【问题标题】:Passing Django template variables into javascript in GAE在 GAE 中将 Django 模板变量传递给 javascript
【发布时间】:2011-05-09 22:10:32
【问题描述】:

我正在尝试使用 Google 的可视化示例创建一个 wordcloud:

<link rel="stylesheet" type="text/css" href="http://visapi-gadgets.googlecode.com/svn/trunk/wordcloud/wc.css"/>
<script type="text/javascript" src="http://visapi-gadgets.googlecode.com/svn/trunk/wordcloud/wc.js"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>


<div id="wcdiv"></div>
<script type="text/javascript">
  google.load("visualization", "1");
  google.setOnLoadCallback(draw);
  function draw() {
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Text1');
    data.addRows(160);
 {{datamade}}
    var outputDiv = document.getElementById('wcdiv');
    var wc = new WordCloud(outputDiv);
    wc.draw(data, null);
  }
</script>

我在 main.py 文件中创建 {{datamade}},然后将其作为模板变量传递:

   tweets1 = []

    fetched = urlfetch.fetch("http://api.twitter.com/1/statuses/user_timeline.json?screen_name="+tweets.username+"&count=200")
    statustext = json.loads(fetched.content)

    for tweetInfo in statustext:
     tweets1.append(tweetInfo["text"])

    datamake = []

    n = 1
    for n in range(160):
   tweet = tweets1[n]
   datamake.append("data.setCell("+str(n)+", 0, '"+tweet+"');")

    datamade = '<br>'.join(datamake)


    content_values = {
        'datamade':datamade,
        'username':tweets.username,
        }

当我打印 {{datamade}} 时,我看到了正确的 Javascript 代码。当我将这些值硬编码到我的 statuspage.html 中时,javascript 会正确执行。但是当我将变量直接传递给 javascript 时,javascript 无法正常执行。

我的 javascript 在模板值被传递之前执行吗?不知道如何对此进行调整。我会很感激任何建议。

免责声明:我完全是新手。

谢谢! 杰克

【问题讨论】:

  • 尝试使用'datamade': SafeString(datamade) 而不是'datamade': database。 Django 可能会转义您的 javascript/html,而使用 SafeString 会阻止这种情况。

标签: javascript python django google-app-engine


【解决方案1】:

Jake,看起来您正在将“
”标签放入您的 js 代码中。 'datamade' 可能是:

data.setCell('foo', 0, 'bar');&lt;br&gt;data.setCell('foo', 0, 'bar');

这不是可执行的 js,因为 js 解释器不读取 html 标签。您实际上是在编写一个不完整的比较表达式(没有什么比一个名为 br 的变量少)。不要试图在代码中插入分页符,只需加入一个空字符串即可。datamade = ''.join(datamake)

编辑: 但总的来说,使用循环打印出 100 多行 js 并不是一个好习惯。您最好将整个对象以 json 格式发送到 js 中,然后在客户端中循环。

我建议这样做:

<link rel="stylesheet" type="text/css" href="http://visapi-gadgets.googlecode.com/svn/trunk/wordcloud/wc.css"/>
<script type="text/javascript" src="http://visapi-gadgets.googlecode.com/svn/trunk/wordcloud/wc.js"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>


<div id="wcdiv"></div>
<script type="text/javascript">
  google.load("visualization", "1");
  google.setOnLoadCallback(draw);
  function draw() {
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Text1');
    data.addRows(160);
    var tweets = {{tweets}};

    for (var i in tweets) {
       data.setCell(i, 0, tweets[i]);
    }

    var outputDiv = document.getElementById('wcdiv');
    var wc = new WordCloud(outputDiv);
    wc.draw(data, null);
  }
</script>

让你的服务器文件显示以下内容:

tweets1 = []

fetched = urlfetch.fetch("http://api.twitter.com/1/statuses/user_timeline.json?screen_name="+tweets.username+"&count=200")
statustext = json.loads(fetched.content)

for tweetInfo in statustext:
 tweets1.append(tweetInfo["text"])

tweetsJson = json.dumps(tweets1)

content_values = {
    'tweets':tweetsJson,
    'username':tweets.username,
    }

【讨论】:

  • 谢谢老兄,由于某种原因仍然无法正常工作。此外,代码需要一个变量,而不是一个字符串:visapi-gadgets.googlecode.com/svn/trunk/wordcloud/doc.html
  • 是的,我明白了。你对最后一部分是对的。我肯定会检查 python 吐出的 javascript 代码。查看页面上的源代码以查看它并检查语法错误。
【解决方案2】:

我建议对您的代码进行一些更改。不要生成 javascript 调用 (data.setCell),而是生成表格并让 Google 的 DataTable 处理它。

import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.api import urlfetch

class GetTweetsHandler(webapp.RequestHandler):
    def get(self):
        user = self.request.get('user', 'someuser')
        fetched = urlfetch.fetch("http://api.twitter.com/1/statuses/user_timeline.json"
                                 "?screen_name=" + user + "&count=200")
        tweets = json.loads(fetched.content)

        data = {'cols': [{'type': 'string', 'label': 'Tweets'}],
                'rows': [{'c': [{'v': tweet["text"]}]} for tweet in tweets]}

        template_values = {'tweet_data': json.dumps(data),
                           'user': user}
        path = os.path.join(os.path.dirname(__file__), 'index.html')
        self.response.out.write(template.render(path, template_values))


 def main():
   application = webapp.WSGIApplication([('/gettweets', GetTweetsHandler)],
                                        debug=True)
   run_wsgi_app(application)

 if __name__ == '__main__':
   main()

那么您只需将生成的数据表传递给 Google 的数据表即可。幸运的是,这是对您的模板的一个非常小的改动:

<html>
<head>
    <link rel="stylesheet" type="text/css" href="http://visapi-gadgets.googlecode.com/svn/trunk/wordcloud/wc.css"/>
    <script type="text/javascript" src="http://visapi-gadgets.googlecode.com/svn/trunk/wordcloud/wc.js"></script>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1");
      google.setOnLoadCallback(draw);
      function draw() {
        var tweet_data = {{tweet_data}};
        var data = new google.visualization.DataTable(tweet_data);
        var outputDiv = document.getElementById('wcdiv');
        var wc = new WordCloud(outputDiv);
        wc.draw(data, null);
      }
    </script>
</head>
<body>
    <div id="wcdiv"></div>
    <form method='get'>
       <input type='text' name='user' value="{{user}}"></input>
       <input type='submit'></input>
    </form>
</body>
</html>

拨打电话到http://localhost:8080/gettweets/someuser

【讨论】:

  • 顺便说一句,您可以在此处找到数据表对象字面量表示法的语法:code.google.com/apis/visualization/documentation/… 查看示例。
  • 非常感谢!由于某种原因,在 GetTweetsHandler template_values = {'tweet_data': json.dumps(data)} NameError: name 'data' is not defined 中出现以下错误:main.py",第 54 行
  • 你确定你复制了上面的那行吗?它应该是一个工作示例,我确实对其进行了测试。
  • 哇!它工作,非常感谢。完成后我会发给你最终版本。
  • 快速跟进:如何将表单中的输入传递到 Action:URL?换句话说,如果gettweets/someuser调用了GetTweetsHandler方法,我该如何从用户输入到表单中调用呢?
猜你喜欢
  • 2018-12-03
  • 1970-01-01
  • 2019-04-03
  • 2014-11-30
  • 2020-04-24
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
相关资源
最近更新 更多