1

Usually I did many times without problems but now it's different and I don't know why .

I'm just trying to display a list on html page using Flask and Jinja2.

And here is my piece of code.

__init__.py
    bpPortfolioList = Blueprint('portfolio', __name__)
    @bpPortfolioList.route('/list', methods=['GET', 'POST'])
    @is_log_in
    def plist():
        portfolio = None
        if session['profile'] == 1:
            print('agent')
            portfolio = mongo.db.users.find({"agentid": session['userid']}, {"portfolio": 1})


        for p in portfolio:
            print(p)

        return render_template('portfolio/list.html', portfolios=portfolio)

I have catch the output of portfolio and here is the result :

{'_id': 10, 'portfolio': {'id': 8476, 'description': '', 'mode': 'Closed', 'accounts': [{'id': 123456, 'account_type': 'None', 'category': '1', 'owner': None, 'ratio': 100, 'status': '1'}]}}
{'_id': 1}
{'_id': 11, 'portfolio': {'id': 4983, 'description': '', 'mode': 'Closed', 'accounts': []}}
{'_id': 13, 'portfolio': {'id': 1226, 'description': '', 'mode': 'Closed', 'accounts': []}}
{'_id': 15, 'portfolio': {'id': 8786, 'description': '', 'mode': 'Closed', 'accounts': []}}
{'_id': 19, 'portfolio': {'id': 7995, 'description': '', 'mode': 'Closed', 'accounts': []}}

Then the HTML :

 <tbody>
   {% for p in portfolios %}
   <tr>
      <td>{{ p.id }}</td>
      <td>{{ p.mode }}</td>
      {% for c in p.accounts %}
         <td>{{ c.id }}</td>
         <td>{{ c.status }}</td>
         <td>{{ c.ratio }}</td>
      {% endfor %}
   </tr>
   {% endfor %}
 </tbody>

At the result I got nothing, except the table header

Any idea what the problem ?

Thanks for your help.

6
  • 1
    Is the return value by mongo.db.users.find a generator? If so all your contents are consumed by the for statement. Also, your template may in fact not match up with the data structure, as what is yielded should be accessible via p['portfolio']['id'] and so on. Commented May 2, 2019 at 1:31
  • do you think the content has been consumed by for ? how ? Commented May 2, 2019 at 1:50
  • Try copy/pasting the for loop (so attempt to loop twice over the same portfolio assignment) and see if you get twice the output. Commented May 2, 2019 at 2:00
  • I didn't know that,and it's good to know it. However to get access still does not work. I have tested 'p._id' it's working fine but p['portfolio']['id'] and p.portfolio.id does not work Commented May 2, 2019 at 2:03
  • When I use your suggestion p['portfolio']['id'] I got the following error: jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'portfolio' Commented May 2, 2019 at 2:07

2 Answers 2

3

The issue is not with jinja2 but with the way you're manipulating the result from your query. pymongo's find method returns an object of type Cursor, which sort of behaves like an iterator, namely once you consume it once, it's exhausted and you cannot iterate it again. This answer may help you understand how the Cursor type works. So to get this working, just convert results from the query to a list:

portfolio = list(mongo.db.users.find({"agentid": session['userid']}, {"portfolio": 1}))

Sign up to request clarification or add additional context in comments.

14 Comments

and how to get nested data access ?
once it's a list you can access each element by index, and each element should be an object allowing you to access its attributes with dot notation, just as you are doing in the template
you mean the html template still appears empty or are you getting a different error?
using this : {% for p in portfolios %} <tr> <td>{{ p._id }}</td> <td>{{ p['portfolio'] }}</td> </tr> {% endfor %} works
and using: {% for p in portfolios %} <tr> <td>{{ p._id }}</td> <td>{{ p['portfolio'] }}</td> <td>{{ p.portfolio.id }}</td> </tr> {% endfor %} gives the same error
|
0

I just figure out that some document from db has missing attribut like:

portfolio is missing and also accounts are emtpy.

{'_id': 10, 'portfolio': {'id': 8476, 'description': '', 'mode': 'Closed', 'accounts': [{'id': 123456, 'account_type': 'None', 'category': '1', 'owner': None, 'ratio': 100, 'status': '1'}]}}
**{'_id': 1}**
{'_id': 11, 'portfolio': {'id': 4983, 'description': '', 'mode': 'Closed', 'accounts': []}}

By adding the following code it solves my problem :

new_pf = []
    for p in pf:
        if 'portfolio' in p:
            if 'accounts' in p['portfolio'] and p['portfolio']['accounts']:
                new_pf.append(p)

Thanks for your support

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.