使用Python / Django中的yield语句迭代json

时间:2017-10-21 11:02:40

标签: python json django

Django Model中有一个名为json_field的char字段。我试图从视图迭代它,但它只返回一个结果,如return语句。我试图找出如何使用yield迭代json_field。

模型对象返回的结果如下:

id : 1
title : "Some Title"  
json_field : [{"key":"value","key2":"value2"},{"key":"value","key2":"value2"}]
created : "Sat Oct 21 2017 14:00:53 GMT+0300 (+03)"

view.py

import json

def MyView(request):
  model_query = MyModel.objects.all() or MyModel.objects.filter or exclude...

  for item in model_query:
      data_item = json.loads(item.json_field)

  template = "template.html"
  context = {"title":title, "data_item":data_item}

  return render(request, template, context)
template.html中的

{% for query_item in model_query %}
<table>
    <thead>
        <tr>
            <th>{{ query_item.title }} - {{ query_item.created }}</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th>Some Heading </th>
            <th>Some Heading </th>

        </tr>

        <!-- json data -->
        {% for item in data_item  %}
        <tr>
            <th>{{ item.key }}</th>    
            <td>{{ item.key2|floatformat:2 }}</td>
        </tr>
        {% endfor %}
        <!-- json data -->

    </thead>
</table><

{% endfor %}

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:1)

您可以为模板准备数据集。

# Fetch data from db as queryset of dicts
items = list(MyModel.objects.filter().values('title', 'created', 'json_field'))

# Decode json in-place
for item in items:
    item['json_field'] = json.loads(item['json_field'])

context = {"title":title, "items": items}

然后浏览模板中的项目:

{% for item in items %}
<table>
    <thead>
        <tr>
            <th>{{ item.title }} - {{ item.created }}</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th>Some Heading </th>
            <th>Some Heading </th>

        </tr>

        <!-- json data -->
        {% for entry in item.json_field  %}
        <tr>
            <th>{{ entry.key }}</th>    
            <td>{{ entry.key2|floatformat:2 }}</td>
        </tr>
        {% endfor %}
        <!-- json data -->

    </thead>
</table><

{% endfor %}

答案 1 :(得分:1)

如果您正在使用PostgreSQL,则可以使用JSONField。它使用postgres的jsonb类型,该类型针对保留json可序列化文本进行了优化。

如果没有,您仍然可以使用django-jsonfield。它几乎提供了相同的功能,即使django的JSONField的一些很酷的功能不可用(如this kind of lookups)。

如果这些都不适合您,您还可以通过继承CharField或TextField并覆盖某些函数来实现自己的JSONField。这样,您就不需要在视图中使用字段的任何逻辑。

编辑: 如果您发现难以改变您的领域或不想出于任何原因这样做,您可以在您的视图中执行此操作:

  for item in model_query:
     item.loaded_json = json.loads(item.json_field)

然后您可以像模板中的普通字段一样使用它:

  {% for query_item in model_query %}
      {% for item in query_item.loaded_json %}
           <span>{{ item.key }}</spam>
      {% endfor %}
  {% endfor %}

答案 2 :(得分:0)

感谢您更新代码!

现在我将重构json.load()的dicts列表,以便您可以使用它。这比模板中的错位更好。

连接由:

完成
my_dict = dict()
for d in data_item 
    my_dict.update( d )

如果要合并,请检查此主题:

How to merge two dictionaries in a single expression?

答案 3 :(得分:0)

您好!

解决方案取决于您的目的。

如果要构建json数组列表,请使用comprehensions:

data_items = [json.loads(item.json_field) for item in model_query]

...或json数组的生成器:

data_items = (json.loads(item.json_field) for item in model_query)

如果你想拥有一个json对象数组,试试这个:

data_items = []
for item in model_query:
    data_items.extend(json.loads(item.json_field))

然后您可以使用data_items作为模板上下文。

小提示:如果使用PostgreSQL或MySQL,可以在ORM级别使用JSONField。如果您计划对此字段进行任何筛选查询,请考虑此方法。作为额外的好处,JSON编码/解码将是开箱即用的。