【问题标题】:Iterating data from Joined Tables using Jinja2 Nested For Loops使用 Jinja2 嵌套 For 循环从连接表中迭代数据
【发布时间】:2018-11-15 20:56:43
【问题描述】:

出于本示例的目的,请考虑以下table,它有一个parent 行迭代“订单”列表,每个“订单”有几个child 行迭代一个给定的“项目”列表“命令”。

当我们使用query 渲染我们的模板时,“订单”和“商品”列表包含在单独的tables 中:

def order_items_template():
    return render_template('order_items_template.html', 
      order_items_query = db.session.query(orders)
      .join(items, orders.id == items.order_id)
      .all())

请注意,我们还使用bootstrap collapsible accordion 来显示父/子行。

{% for order in orders %} 

    <tr data-toggle="collapse" data-target="#{{ order.number }}" class="clickable">
        <td>{{ order.number }}</td>        
    </tr>

        {% for item in order %}
            <tr class="no-border collapse" id="{{ order.number }}">
                <td>{{ item.name }}</td>                                          
            </tr>
        {% endfor %} 

{% endfor %}  

此外,我们使用sqlalchemy ForeignKey relationship 连接这两个表:

class items (db.Model):
   id = db.Column('id', db.Integer, primary_key = True)
   item = db.Column(db.String(100)) 
   order_id = db.Column(db.Integer)

class orders (db.Model):
   id = db.Column('id', db.Integer, primary_key = True)
   orders = db.Column(db.String(100)) 
   item_id = db.Column(db.Integer, db.ForeignKey('items.order_id'), nullable=False)
   item_relashionship = relationship("items")

虽然parent 行显示,但rows 中的数据却没有。有谁看到问题出在哪里?

编辑:通过将“子”jinja2 loop{{ % for item in order % }} 更改为{{ % for item in order.items % }},如下所示,不会返回任何数据,bootstrap accordion 已“损坏”且不再折叠。

出于测试目的,将{{ order.item_relashionship.name }} 占位符添加到“父循环”会返回匹配order_iditem 的名称,这显然是错误的。

我们想要的是每个order 对应的items 列表。这一定与两个表之间的关系有关,但我无法弄清楚缺少什么。

【问题讨论】:

    标签: python python-3.x flask jinja2 flask-sqlalchemy


    【解决方案1】:

    当您查询结果并将数据传递给 html 时,请尝试添加一个包含订单号详细信息的临时列,以便您可以遍历订单并将其显示在屏幕上。我之前也遇到过类似的需求,通过下面的方法实现了。

    queryset1= table1.objects.all().annotate(order=Value('value1', CharField()))
    queryset2= table2.objects.all().annotate(order=Value('value2', CharField()))
    all_items = list(queryset1) + list(queryset2) 
    all_items_feed = sorted(all_items, key=lambda obj: obj.type)
    return render(request, 'page.html', {'all_items_feed' : all_items_feed})
    

    并在 html 页面中通过检查以下条件来遍历 all_items_feed

    {% if all_items_feed %}
        {% for items in all_items_feed %}
            {% if items.order == 'value1' %}
            populate the html collapse content for every order here
    

    【讨论】:

    • 有道理。我从queryset1 得到AttributeError: 'list' object has no attribute 'annotate',但需要弄清楚它来自哪里。
    • 据我了解,我将值初始化为list,而我应该使用instances,但我的知识仅限于启动后者而不是前者。
    • 有什么可以帮忙的吗?
    【解决方案2】:

    一个简单的猜测,但我认为您需要类似以下内容:

    {% for item in order.items %} <-- Note the change in order to order.items
        <tr class="no-border collapse" id="{{ order.number }}">
            <td>{{ item.name}}</td>                                          
        </tr>
    {% endfor %} 
    

    您需要为您的子数据遍历对象items

    【讨论】:

    • 我相信更接近解决方案,因为这个问题肯定与orderitems 之间的“连接”有关,但仍然不起作用。我已经在我的初始帖子中添加了一个包含更多详细信息的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多