Python Dict 中出现的特殊字符从 AWS 构建并通过 django 视图传递给 js

Posted

技术标签:

【中文标题】Python Dict 中出现的特殊字符从 AWS 构建并通过 django 视图传递给 js【英文标题】:Special Characters Showing up in Python Dict built form AWS and being passed to js through django view 【发布时间】:2015-09-16 10:50:58 【问题描述】:

我正在调用有关我的基础架构的一些信息并尝试构建一个字典,我可以将其转换为 json 作为对象并将其传递给 javascript 以显示。

我已经尝试使用 json.dumps 和 simplejson.dumps 到字典中。

我假设它是因为 dict 在其中嵌套了 dicts。

这是数据的结构

python 打印出通过 django 传递给网页的数据。

    'SecurityGroup:eiddo-slave-elb': 'rules': 'ingress': 'to_port': '0000', 
'ingress_grants': "'sg-000000': 'cidr': 'None', 'group_id': 'sg-00000', 
'grant_name': 'None'", 'from_port': '7001', 'protocol': 'tcp', 'groups': '', 
'egress': 'to_port': '0001', 'egress_grants': "'sg-000000': 'cidr': 'None', 
'group_id': 'sg-00000', 'grant_name': 'None'", 'from_port': '0000', 'protocol': 'tcp', 'groups': '', 'id': 'SecurityGroup:eiddo-slave-elb', 'tags': ''

数据的网络控制台输出。语法错误来自 jquery,因为它无法解析数据来完成循环。如您所见,传递的数据中有很多特殊字符。我什至尝试将 dict 的字符串编码为 UTF-8

    Error: Syntax error, unrecognized expression: 'SecurityGroup:eiddo-slave-elb': 'rules': 'ingress': 'to_port': 
'7001', 'ingress_grants': "'sg-000000000': 
'cidr': 'None', 'group_id': 'sg-54b09d31', 
'grant_name': 'None'", 'from_port': 
'7001', 'protocol': 'tcp', 'groups': '', 
'egress': 'to_port': '0000', 'egress_grants': 
"'sg-00000000': 'cidr': 'None',
 'group_id': 'sg-00000000', 'grant_name': 
'None'", 'from_port': '7001', 'protocol': 
'tcp', 'groups': '', 'id': 
'SecurityGroup:eiddo-slave-elb', 'tags': '', 
'SecurityGroup:asgard': 'rules': 'ingress': 
'to_port': 'None', &#39

JS var security_groups = "security_groups";

    $(security_groups).each(function( index ) 
      console.log(security_groups[index]);
    );

Python 代码

    def getSG():
        conn = boto.ec2.connect_to_region('us-west-2',aws_access_key_id='', aws_secret_access_key='')
        rs = conn.get_all_security_groups()
        rule_list = 
        ig_grants = 
        eg_grants = 
        sg_dict = 
        flag = True

        for item in rs:
            rules = item.rules
            for rule in item.rules:
                for grant in rule.grants:
                    ig_grants[str(grant)] = 'cidr': str(grant.cidr_ip).strip(), 
                                             'group_id': str(grant.group_id).strip(), 
                                             'grant_name': str(grant.name).strip()

                rule_list['ingress']= 'from_port': str(rule.from_port).strip(), 
                                       'to_port': str(rule.to_port).strip(), 
                                       'groups': str(rule.groups).strip(), 
                                       'protocol': str(rule.ip_protocol).strip(),
                                       'ingress_grants': str(ig_grants).strip()
                                       
                ig_grants = 

            for rule in item.rules:
                for grant in rule.grants:
                    eg_grants[str(grant)] = 'cidr': str(grant.cidr_ip).strip(), 
                                             'group_id': str(grant.group_id).strip(), 
                                             'grant_name': str(grant.name).strip()

                rule_list['egress']= 'from_port': str(rule.from_port).strip(), 
                                      'to_port': str(rule.to_port).strip(), 
                                      'groups': str(rule.groups).strip(), 
                                      'protocol': str(rule.ip_protocol).strip(), 
                                      'egress_grants': str(eg_grants).strip()
                                      
                eg_grants = 
            sg_dict[str(item)] = 'id':str(item).strip(), 'rules':rule_list, 'tags':str(item.tags).strip()
            rule_list = 

        return sg_dict

    def index(request):
        conn = boto.ec2.connect_to_region('us-west-2',aws_access_key_id='', aws_secret_access_key='')
        #instances = get_ec2_instances(conn)
        rs = conn.get_all_security_groups()
        security_groups = getSG()
        print security_groups

        template = loader.get_template('index.html')
        context = RequestContext(request, 'security_groups': security_groups,)
        return HttpResponse(template.render(context))

我这里的目标是把它作为一个json字符串传递给js,然后转换成一个json对象。

我知道我的 js 中没有包含 JSON.parse,因为我想让字符串在没有特殊字符的情况下看起来正确。因为当我这样做时

    JSON.parse(security_groups);

我收到以下错误:

SyntaxError: JSON.parse: expected property name or '' at line 1 column 2 of the JSON data

【问题讨论】:

【参考方案1】:

security_groups 在您的模板中输出 Python 字典的 HTML 转义表示。这不是 Javascript 可以正确解析的。

改为使用 JSON(也称为 JavaScript 对象表示法),JS 会知道如何加载。


为此,

在你的视图代码中,改变

context = RequestContext(request, 'security_groups': security_groups,)

到:

context = RequestContext(request, 'security_groups': json.dumps(security_groups),)

(您需要在文件顶部添加import json

并且在 JS 代码中,更改:

var security_groups = "security_groups";

到:

var security_groups = JSON.parse(" security_groups|escapejs ");

或者干脆(但不推荐):

var security_groups =  security_groups ;

【讨论】:

谢谢,真的有帮助,但我不明白其中的区别,只是我错过了ehe escapejs吗?还是我必须在请求上下文中转储到 json? 你必须做这两件事。将其转储为 JSON 可确保它可以在 JS 中重新加载。 Escape JS 确保 JS 可以真正解析字符串(因为 JSON 包含 '"' 符号,否则会中断)。

以上是关于Python Dict 中出现的特殊字符从 AWS 构建并通过 django 视图传递给 js的主要内容,如果未能解决你的问题,请参考以下文章

Python数据类型:序列(字符串str列表list元组tuple字典dict范围range)

Python - 从键替换特殊字符,字典中的值

用python统计list中各元素出现的次数(同理统计字符串中各字符出现的次数)

Python数据类型:序列(字符串str列表list元组tuple字典dict范围range) 和集合set

python Dict python 字典操作

Python_68类的特殊成员之dict