используя коллекцию mongoDB на одной странице дважды - PullRequest
0 голосов
/ 30 мая 2018

Hi2all!У меня есть: 1) коллекция монго:

[{_id:ObjectId("5b0d5fb624d22e1b4843c06b")
collectionName:"collection0"
collectionCaption:"caption1"}

{_id:ObjectId("5b0d5fb824d22e1b4843d4c1")
collectionName:"collection1"
collectionCaption:"caption1"}

{_id:ObjectId("5b0d5fb924d22e1b4843d74a")
collectionName:"collection2"
collectionCaption:"caption1"}

{_id:ObjectId("5b0d5fb924d22e1b4843d7b0")
collectionName:"collection3"
collectionCaption:"caption1"}]

2) колба с видом:

def index():
    a = mongo.db.collectionsNames.find()
    return render_template('index.html', collectionsNames=a)

3) шаблоны: index.html с расширением base.html.base.html:

{% extends "bootstrap/base.html" %} 
{% block content %}
    <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
        {% for asd in collectionsNames %}
            <a class="dropdown-item" href="/{{ asd["collectionName"] }}">{{ asd["collectionCaption"] }}</a>
        {% endfor %}

    </div>
    {% block contentBase %} {% endblock %}
{% endblock %}

index.html:

{% extends "base.html" %}
{% block contentBase %}
    {% for zxc in collectionsNames %}
        {{ zxc["collectionName"] }}
    {% endfor %}
{% endblock %}

Вопрос: почему, если base и index используют одну и ту же переменную коллекции, шаблон индекса ничего не показывает?

Но если в представлении код:

def index():
        a = mongo.db.collectionsNames.find()
        b = mongo.db.collectionsNames.find()
        return render_template('index.html', collectionsNames1=a, collectionsNames2=b)

и в шаблонах я использую разные переменные, шаблон индекса покажет мне данные.

1 Ответ

0 голосов
/ 30 мая 2018

mongo.db.collectionsNames.find() возвращает курсор: print(mongo.db.collectionsNames.find()) дает <pymongo.cursor.Cursor object at 0x7fd3854d5710>.

Чтобы упростить (но неправильно) курсор, это особый тип экземпляра, который извлекает данные из фрагмента базы данных с помощьючанк, так что если вы хотите получить 1 000 000 первых элементов в дБ, вы фактически не храните 1M элементов в оперативной памяти, вы итерируете 100 на 100 элементов (например).Курсор обрабатывает это волшебным образом.

Как бы то ни было, вы не можете зацикливаться несколько раз на одном и том же курсоре, и вам никогда не следует помещать курсор в список, подобный list(cursor_instance) (потому что, если ваш запрос запрашивает продукт 1M, выполните этодобавьте все эти продукты в оперативную память).


Итак, теперь, как вы можете справиться с этим.В большинстве случаев я бы сказал, что лучше вызывать метод, когда вам это нужно, дважды, если это необходимо.

Но здесь вы находитесь в среде Jinja, и если я прав, вызов методов в шаблоне Jinja невозможен.

Способ сделать это - использовать свойства.

class LazyCollection(object):

    @property
    def collections_names(self):
         return mongo.db.collectionsNames.find()


lazycoll = LazyCollection()
return render_template('index.html', collectionsNames=lazycoll)

Затем в вашем шаблоне:

{% for asd in collectionsNames.collections_names %}
    <p>{{ asd.foo }}</p>
{% endfor %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...