forked from orbit-oss/flask
Merge branch '1.0-maintenance'
This commit is contained in:
commit
ac6746d1be
11 changed files with 173 additions and 162 deletions
|
|
@ -34,7 +34,7 @@ Snippet Archives <http://flask.pocoo.org/snippets/>`_.
|
|||
jquery
|
||||
errorpages
|
||||
lazyloading
|
||||
mongokit
|
||||
mongoengine
|
||||
favicon
|
||||
streaming
|
||||
deferredcallbacks
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ example that shows how you would use jQuery and Flask nonetheless::
|
|||
return render_template('index.html')
|
||||
|
||||
As you can see I also added an `index` method here that renders a
|
||||
template. This template will load jQuery as above and have a little form
|
||||
template. This template will load jQuery as above and have a little form where
|
||||
we can add two numbers and a link to trigger the function on the server
|
||||
side.
|
||||
|
||||
|
|
|
|||
103
docs/patterns/mongoengine.rst
Normal file
103
docs/patterns/mongoengine.rst
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
MongoDB with MongoEngine
|
||||
========================
|
||||
|
||||
Using a document database like MongoDB is a common alternative to
|
||||
relational SQL databases. This pattern shows how to use
|
||||
`MongoEngine`_, a document mapper library, to integrate with MongoDB.
|
||||
|
||||
A running MongoDB server and `Flask-MongoEngine`_ are required. ::
|
||||
|
||||
pip install flask-mongoengine
|
||||
|
||||
.. _MongoEngine: http://mongoengine.org
|
||||
.. _Flask-MongoEngine: https://flask-mongoengine.readthedocs.io
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
Basic setup can be done by defining ``MONGODB_SETTINGS`` on
|
||||
``app.config`` and creating a ``MongoEngine`` instance. ::
|
||||
|
||||
from flask import Flask
|
||||
from flask_mongoengine import MongoEngine
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['MONGODB_SETTINGS'] = {
|
||||
"db": "myapp",
|
||||
}
|
||||
db = MongoEngine(app)
|
||||
|
||||
|
||||
Mapping Documents
|
||||
-----------------
|
||||
|
||||
To declare a model that represents a Mongo document, create a class that
|
||||
inherits from ``Document`` and declare each of the fields. ::
|
||||
|
||||
import mongoengine as me
|
||||
|
||||
class Movie(me.Document):
|
||||
title = me.StringField(required=True)
|
||||
year = me.IntField()
|
||||
rated = me.StringField()
|
||||
director = me.StringField()
|
||||
actors = me.ListField()
|
||||
|
||||
If the document has nested fields, use ``EmbeddedDocument`` to
|
||||
defined the fields of the embedded document and
|
||||
``EmbeddedDocumentField`` to declare it on the parent document. ::
|
||||
|
||||
class Imdb(me.EmbeddedDocument):
|
||||
imdb_id = me.StringField()
|
||||
rating = me.DecimalField()
|
||||
votes = me.IntField()
|
||||
|
||||
class Movie(me.Document):
|
||||
...
|
||||
imdb = me.EmbeddedDocumentField(Imdb)
|
||||
|
||||
|
||||
Creating Data
|
||||
-------------
|
||||
|
||||
Instantiate your document class with keyword arguments for the fields.
|
||||
You can also assign values to the field attributes after instantiation.
|
||||
Then call ``doc.save()``. ::
|
||||
|
||||
bttf = Movie(title="Back To The Future", year=1985)
|
||||
bttf.actors = [
|
||||
"Michael J. Fox",
|
||||
"Christopher Lloyd"
|
||||
]
|
||||
bttf.imdb = Imdb(imdb_id="tt0088763", rating=8.5)
|
||||
bttf.save()
|
||||
|
||||
|
||||
Queries
|
||||
-------
|
||||
|
||||
Use the class ``objects`` attribute to make queries. A keyword argument
|
||||
looks for an equal value on the field. ::
|
||||
|
||||
bttf = Movies.objects(title="Back To The Future").get_or_404()
|
||||
|
||||
Query operators may be used by concatenating them with the field name
|
||||
using a double-underscore. ``objects``, and queries returned by
|
||||
calling it, are iterable. ::
|
||||
|
||||
some_theron_movie = Movie.objects(actors__in=["Charlize Theron"]).first()
|
||||
|
||||
for recents in Movie.objects(year__gte=2017):
|
||||
print(recents.title)
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
There are many more ways to define and query documents with MongoEngine.
|
||||
For more information, check out the `official documentation
|
||||
<MongoEngine_>`_.
|
||||
|
||||
Flask-MongoEngine adds helpful utilities on top of MongoEngine. Check
|
||||
out their `documentation <Flask-MongoEngine_>`_ as well.
|
||||
|
|
@ -1,144 +1,7 @@
|
|||
.. mongokit-pattern:
|
||||
:orphan:
|
||||
|
||||
MongoKit in Flask
|
||||
=================
|
||||
MongoDB with MongoKit
|
||||
=====================
|
||||
|
||||
Using a document database rather than a full DBMS gets more common these days.
|
||||
This pattern shows how to use MongoKit, a document mapper library, to
|
||||
integrate with MongoDB.
|
||||
|
||||
This pattern requires a running MongoDB server and the MongoKit library
|
||||
installed.
|
||||
|
||||
There are two very common ways to use MongoKit. I will outline each of them
|
||||
here:
|
||||
|
||||
|
||||
Declarative
|
||||
-----------
|
||||
|
||||
The default behavior of MongoKit is the declarative one that is based on
|
||||
common ideas from Django or the SQLAlchemy declarative extension.
|
||||
|
||||
Here an example :file:`app.py` module for your application::
|
||||
|
||||
from flask import Flask
|
||||
from mongokit import Connection, Document
|
||||
|
||||
# configuration
|
||||
MONGODB_HOST = 'localhost'
|
||||
MONGODB_PORT = 27017
|
||||
|
||||
# create the little application object
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(__name__)
|
||||
|
||||
# connect to the database
|
||||
connection = Connection(app.config['MONGODB_HOST'],
|
||||
app.config['MONGODB_PORT'])
|
||||
|
||||
|
||||
To define your models, just subclass the `Document` class that is imported
|
||||
from MongoKit. If you've seen the SQLAlchemy pattern you may wonder why we do
|
||||
not have a session and even do not define a `init_db` function here. On the
|
||||
one hand, MongoKit does not have something like a session. This sometimes
|
||||
makes it more to type but also makes it blazingly fast. On the other hand,
|
||||
MongoDB is schemaless. This means you can modify the data structure from one
|
||||
insert query to the next without any problem. MongoKit is just schemaless
|
||||
too, but implements some validation to ensure data integrity.
|
||||
|
||||
Here is an example document (put this also into :file:`app.py`, e.g.)::
|
||||
|
||||
from mongokit import ValidationError
|
||||
|
||||
def max_length(length):
|
||||
def validate(value):
|
||||
if len(value) <= length:
|
||||
return True
|
||||
# must have %s in error format string to have mongokit place key in there
|
||||
raise ValidationError('%s must be at most {} characters long'.format(length))
|
||||
return validate
|
||||
|
||||
class User(Document):
|
||||
structure = {
|
||||
'name': unicode,
|
||||
'email': unicode,
|
||||
}
|
||||
validators = {
|
||||
'name': max_length(50),
|
||||
'email': max_length(120)
|
||||
}
|
||||
use_dot_notation = True
|
||||
def __repr__(self):
|
||||
return '<User %r>' % (self.name)
|
||||
|
||||
# register the User document with our current connection
|
||||
connection.register([User])
|
||||
|
||||
|
||||
This example shows you how to define your schema (named structure), a
|
||||
validator for the maximum character length and uses a special MongoKit feature
|
||||
called `use_dot_notation`. Per default MongoKit behaves like a python
|
||||
dictionary but with `use_dot_notation` set to ``True`` you can use your
|
||||
documents like you use models in nearly any other ORM by using dots to
|
||||
separate between attributes.
|
||||
|
||||
You can insert entries into the database like this:
|
||||
|
||||
>>> from yourapplication.database import connection
|
||||
>>> from yourapplication.models import User
|
||||
>>> collection = connection['test'].users
|
||||
>>> user = collection.User()
|
||||
>>> user['name'] = u'admin'
|
||||
>>> user['email'] = u'admin@localhost'
|
||||
>>> user.save()
|
||||
|
||||
Note that MongoKit is kinda strict with used column types, you must not use a
|
||||
common `str` type for either `name` or `email` but unicode.
|
||||
|
||||
Querying is simple as well:
|
||||
|
||||
>>> list(collection.User.find())
|
||||
[<User u'admin'>]
|
||||
>>> collection.User.find_one({'name': u'admin'})
|
||||
<User u'admin'>
|
||||
|
||||
.. _MongoKit: https://github.com/namlook/mongokit
|
||||
|
||||
|
||||
PyMongo Compatibility Layer
|
||||
---------------------------
|
||||
|
||||
If you just want to use PyMongo, you can do that with MongoKit as well. You
|
||||
may use this process if you need the best performance to get. Note that this
|
||||
example does not show how to couple it with Flask, see the above MongoKit code
|
||||
for examples::
|
||||
|
||||
from MongoKit import Connection
|
||||
|
||||
connection = Connection()
|
||||
|
||||
To insert data you can use the `insert` method. We have to get a
|
||||
collection first, this is somewhat the same as a table in the SQL world.
|
||||
|
||||
>>> collection = connection['test'].users
|
||||
>>> user = {'name': u'admin', 'email': u'admin@localhost'}
|
||||
>>> collection.insert(user)
|
||||
|
||||
MongoKit will automatically commit for us.
|
||||
|
||||
To query your database, you use the collection directly:
|
||||
|
||||
>>> list(collection.find())
|
||||
[{u'_id': ObjectId('4c271729e13823182f000000'), u'name': u'admin', u'email': u'admin@localhost'}]
|
||||
>>> collection.find_one({'name': u'admin'})
|
||||
{u'_id': ObjectId('4c271729e13823182f000000'), u'name': u'admin', u'email': u'admin@localhost'}
|
||||
|
||||
These results are also dict-like objects:
|
||||
|
||||
>>> r = collection.find_one({'name': u'admin'})
|
||||
>>> r['email']
|
||||
u'admin@localhost'
|
||||
|
||||
For more information about MongoKit, head over to the
|
||||
`website <https://github.com/namlook/mongokit>`_.
|
||||
MongoKit is no longer maintained. See :doc:`/patterns/mongoengine`
|
||||
instead.
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@
|
|||
Larger Applications
|
||||
===================
|
||||
|
||||
For larger applications it's a good idea to use a package instead of a
|
||||
module. That is quite simple. Imagine a small application looks like
|
||||
this::
|
||||
Imagine a simple flask application structure that looks like this::
|
||||
|
||||
/yourapplication
|
||||
yourapplication.py
|
||||
|
|
@ -17,8 +15,10 @@ this::
|
|||
login.html
|
||||
...
|
||||
|
||||
The :ref:`tutorial <tutorial>` is structured this way, see the
|
||||
:gh:`example code <examples/tutorial>`.
|
||||
While this is fine for small applications, for larger applications
|
||||
it's a good idea to use a package instead of a module.
|
||||
The :ref:`tutorial <tutorial>` is structured to use the package pattern,
|
||||
see the :gh:`example code <examples/tutorial>`.
|
||||
|
||||
Simple Packages
|
||||
---------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue