vishnusathyanesan
vishnusathyanesan

Reputation: 303

pymongo with flask

I am trying to return my posts, but instead I get

TypeError: 'Cursor' object is not callable.

How can I correct this? Here is my code:

from flask import Flask  
from flask.ext.pymongo import PyMongo  
app = Flask(__name__)  
mongo = PyMongo(app)  
from pymongo import Connection  
connection = Connection()  
db = connection.test_database  
collection = db.test_collection  

@app.route('/')  
def home_page():  
   post = {"author":"mike","text":"jiii"}  
   posts = db.posts  
   posts.insert(post)  
   return posts.find()

if __name__=='__main__':  
   app.run(debug=True)

Upvotes: 12

Views: 9818

Answers (4)

ask_me
ask_me

Reputation: 473

Use:

from flask_pymongo import Pymongo

instead of:

from flask.ext.pymongo import PyMongo

Upvotes: 0

Eric Schrijver
Eric Schrijver

Reputation: 219

The answers above are both correct. Flask views are expected to return some kind of HTTP response. So you need to process the data and make a response, probably using Flask’s utility functions. Also, the find() method returns a cursor, that you need to iterate over at some point.

You just need to change the last line of the view:

@app.route('/')  
def home_page():  
   post = {"author":"mike","text":"jiii"}  
   posts = db.posts  
   posts.insert(post)  
   return render_template(posts.find(), "index.html")

And provide an index.html that contains something like:

{% for post in posts %}
<h2>Post by {{ post.author}}</h2>
<p>{{ post.text }}</p>
{% endfor %}

Upvotes: 1

Sean Vieira
Sean Vieira

Reputation: 159955

When you return something from a Flask handler it must be one of the following types of things:

When you return the PyMongo Cursor object Flask sees that it is not an instance of flask.Response (actually, flask.Flask.response_class) and not a tuple so it assumes that it must be a WSGI object and attempts to call it (hence the error).

The best solution is to either use flask.jsonfiy to return a JSON response or to create a template to render the posts and use render_template to return the appropriate response.

Upvotes: 7

JohnnyHK
JohnnyHK

Reputation: 311935

find() returns a Cursor object that you must iterate over to access the documents returned by the query. As in:

for post in posts.find():
    # do something with post

Upvotes: 13

Related Questions