【问题标题】:Parse JSON object to Django template将 JSON 对象解析为 Django 模板
【发布时间】:2016-11-13 05:56:58
【问题描述】:

我正在尝试将 JSON 对象解析为 Django 模板,以便我可以将此 json 对象解析为 javascript。

以下是我的视图如何创建 json 对象并将其解析为模板:

    countries = Country.objects.filter(Enabled=True)
    citiesByCountry = {}

    for country in countries:
        citiesInCountry = City.objects.filter(Enabled=True, Country=country)
        cities = []

        for city in citiesInCountry:
            cities.append(city.Name)

        citiesByCountry[country.Name] = cities

    context = {'citiesByCountry': json.dumps(citiesByCountry)}
    return render(request, 'index.html', context)

现在我想以这种方式检索模板的所有键(将是国家/地区):

{% for country in citiesByCountry%}
   <option>{{ country }}</option>
{% endfor %}

但我得到的是字符串中每个字符的选项,而不是整个国家/地区名称。

我尝试使用.item1,但这也没有用。

我没有在上面的示例中显示 JavaScript 代码,因为问题的目的是如何解析和检索 JSON 对象中的字符串。我需要稍后使用 javascript 处理这些数据。具体来说,一旦用户更改国家/地区,我想填充另一个处理城市的下拉列表,因此我想使用 JSON 和 Javascript 来实现这一点,因为我不想在每次更改时刷新页面。

有什么帮助吗?

【问题讨论】:

  • 为什么需要解析成javascript?在您的示例中,您没有这样做
  • 为什么要将citiesByCountry 编码为 JSON?只需将其作为字典传递给context = {'citiesByCountry': citiesByCountry} 之类的上下文,它应该可以工作。
  • 感谢您的回复。我没有在上面的示例中显示 JavaScript 代码,因为问题的目的是如何解析和检索 JSON 对象中的字符串。我需要稍后使用 javascript 处理这些数据。具体来说,一旦用户更改国家/地区,我想填充另一个处理城市的下拉列表,因此我想使用 JSON 和 Javascript 来实现这一点,因为我不想在每次更改时刷新页面。
  • @xyres 我照你说的做了,而且过去工作过,但现在我想使用 JavaScript 填充城市下拉列表,我不确定是否可以将 Python 列表解析为 javascript。
  • @John 在这种情况下,Django 的模板语法将不起作用。您必须完全在 JS 中完成。

标签: python json django


【解决方案1】:

在标题中回答你的问题:

&lt;head&gt;(或某处)中,构建您的县数组:

<script>
    var country_objs = [];
    {% for country in citiesByCountry%}
        country_objs.push({{country|escapejs}});
    {% endfor %}
<\script>

过滤器的文档:https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#escapejs

然后你可以在 JavaScript 中使用它(但不能在 Django 模板中)。例如:

<select id="cities"><\select>
<script>
    var $cities_select = $("#cities");
    $(country_objs).each(function(){
        $cities_select.append('<option value="' + this.id_or_something + '">' + this.name + '<\option>');
    });
<\script>

但是从您的示例中,我不明白为什么您首先需要将其编码为 JSON。为什么不直接将 dict 传递给模板(通过上下文,就像其他所有内容一样)?

附: 抱歉使用 jQuery,我只是懒惰 :)

【讨论】:

  • @John Ah,cmets 包含关于为什么使用 JSON 的额外解释。也许对您的问题进行编辑。对于后代,你知道;)
  • 谢谢。我已经更新了我的问题。我会尝试你的解决方案,我会告诉你的。
  • 我认为这行得通。但由于某种原因,城市价值是“未定义”,我猜这与这条线有关$cities_select.append('&lt;option&gt;' + this.Name + '&lt;\option&gt;');
【解决方案2】:

我认为你有两个选择:

  1. 使用 javascript 解析 &lt;option&gt; 标签中的 JSON。

    <script>
        var json = JSON.parse({{citiesByCountry}});
        //Loop through json and append to <option>
    </script>
    
  2. 添加一个额外的context,它不是 JSON 序列化的。这有点多余,但更简单。

    context = {'citiesByCountry_json': json.dumps(citiesByCountry), 'citiesByCountry': citiesbyCountry}
    

老实说,我会选择第二个选项,因为我不明白为什么首先需要将它发送到 JSON 格式的模板。

【讨论】:

    【解决方案3】:

    当您执行citiesByCountry = json.dumps({'a': "b", 'c': None}) 时,citiesByCountry 是一个字符串。这就是为什么在迭代时会得到一个又一个字符的原因。

    这个字符串代表一个 JSON 对象,你可以“影响”一个 JavaScript 变量:

    var citiesByCountry = {{ citiesByCountry }};
    

    这将输出如下内容:

    var citiesByCountry = {"a": "c", "d": null};
    

    但是,考虑到您想要实现的目标:

    具体来说,一旦用户更改国家/地区,我想填充另一个处理城市的下拉列表

    我强烈建议您结帐django-autocomplete-light,它除了提供自动完成功能外,还提供了filter results based on other fields 的方法。这将为您节省很多精力。

    【讨论】:

      猜你喜欢
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      相关资源
      最近更新 更多