Итерация данных из объединенных таблиц с использованием Jinja2 Nested For Loops - PullRequest
0 голосов
/ 15 ноября 2018

Для целей этого примера рассмотрим следующую table, в которой есть строка parent, повторяющая список «заказов», а каждый «заказ» имеет несколько строк child, повторяющих список «элементов» для данного"order".

Список "orders" и "items" содержится в отдельных tables, объединенных вместе, когда мы отображаем наш шаблон с query:

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 нет.Кто-нибудь видит, в чем проблема?

edit: путем изменения «потомка» jinja2 loop с {{ % for item in order % }} на {{ % for item in order.items % }}, как указано ниже, данные не возвращаются, а bootstrap accordion «ломается» и больше не сворачивается.

В целях тестирования добавление заполнителя {{ order.item_relashionship.name }} в "родительский цикл" возвращает имя item, совпадающее с order_id, что, очевидно, неверно.

Нам нужен соответствующий список items для каждого order.Это должно быть как-то связано с отношениями между двумя таблицами, но я не могу понять, чего не хватает.

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Когда вы запрашиваете результат и передаете данные в 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
0 голосов
/ 16 ноября 2018

Простое предположение, но я думаю, что вам нужно что-то вроде этого:

{% 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 для ваших под-данных

...