Compare commits

..

5 Commits

Author SHA1 Message Date
Stefan Wojcik
3c8e1e5336 clean up the Document._get_collection code 2017-04-30 14:11:03 -04:00
Artemiy
bd4a603e16 Use De Morgan's laws to simplify an expression. (#1531) 2017-04-20 10:27:37 -04:00
Jason
358b80d782 Make the tutorial slightly more intuitive (#1530) 2017-04-20 09:11:38 -04:00
Stefan Wojcik
824ec42005 bump version to v0.13.0 and fill in the changelog and the upgrade docs 2017-04-16 14:08:46 -04:00
Stefan Wójcik
466935e9a3 Unicode support in EmailField (#1527) 2017-04-16 13:58:58 -04:00
6 changed files with 73 additions and 36 deletions

View File

@@ -6,6 +6,11 @@ Development
===========
- (Fill this out as you fix issues and develop your features).
Changes in 0.13.0
=================
- POTENTIAL BREAKING CHANGE: Added Unicode support to the `EmailField`, see
docs/upgrade.rst for details.
Changes in 0.12.0
=================
- POTENTIAL BREAKING CHANGE: Fixed limit/skip/hint/batch_size chaining #1476

View File

@@ -206,7 +206,10 @@ object::
ross.last_name = 'Lawley'
ross.save()
Now that we've got our user in the database, let's add a couple of posts::
Assign another user to a variable called ``john``, just like we did above with
``ross``.
Now that we've got our users in the database, let's add a couple of posts::
post1 = TextPost(title='Fun with MongoEngine', author=john)
post1.content = 'Took a look at MongoEngine today, looks pretty cool.'

View File

@@ -6,6 +6,17 @@ Development
***********
(Fill this out whenever you introduce breaking changes to MongoEngine)
0.13.0
******
This release adds Unicode support to the `EmailField` and changes its
structure significantly. Previously, email addresses containing Unicode
characters didn't work at all. Starting with v0.13.0, domains with Unicode
characters are supported out of the box, meaning some emails that previously
didn't pass validation now do. Make sure the rest of your application can
accept such email addresses. Additionally, if you subclassed the `EmailField`
in your application and overrode `EmailField.EMAIL_REGEX`, you will have to
adjust your code to override `EmailField.USER_REGEX`, `EmailField.DOMAIN_REGEX`,
and potentially `EmailField.UTF8_USER_REGEX`.
0.12.0
******

View File

@@ -23,7 +23,7 @@ __all__ = (list(document.__all__) + list(fields.__all__) +
list(signals.__all__) + list(errors.__all__))
VERSION = (0, 12, 0)
VERSION = (0, 13, 0)
def get_version():

View File

@@ -167,45 +167,63 @@ class Document(BaseDocument):
@classmethod
def _get_collection(cls):
"""Returns the collection for the document."""
# TODO: use new get_collection() with PyMongo3 ?
"""Return a PyMongo collection for the document."""
if not hasattr(cls, '_collection') or cls._collection is None:
db = cls._get_db()
collection_name = cls._get_collection_name()
# Create collection as a capped collection if specified
if cls._meta.get('max_size') or cls._meta.get('max_documents'):
# Get max document limit and max byte size from meta
max_size = cls._meta.get('max_size') or 10 * 2 ** 20 # 10MB default
max_documents = cls._meta.get('max_documents')
# Round up to next 256 bytes as MongoDB would do it to avoid exception
if max_size % 256:
max_size = (max_size // 256 + 1) * 256
if collection_name in db.collection_names():
cls._collection = db[collection_name]
# The collection already exists, check if its capped
# options match the specified capped options
options = cls._collection.options()
if options.get('max') != max_documents or \
options.get('size') != max_size:
msg = (('Cannot create collection "%s" as a capped '
'collection as it already exists')
% cls._collection)
raise InvalidCollectionError(msg)
else:
# Create the collection as a capped collection
opts = {'capped': True, 'size': max_size}
if max_documents:
opts['max'] = max_documents
cls._collection = db.create_collection(
collection_name, **opts
)
# Get the collection, either capped or regular.
if cls._meta.get('max_size') or cls._meta.get('max_documents'):
cls._collection = cls._get_capped_collection()
else:
db = cls._get_db()
collection_name = cls._get_collection_name()
cls._collection = db[collection_name]
# Ensure indexes on the collection unless auto_create_index was
# set to False.
if cls._meta.get('auto_create_index', True):
cls.ensure_indexes()
return cls._collection
@classmethod
def _get_capped_collection(cls):
"""Create a new or get an existing capped PyMongo collection."""
db = cls._get_db()
collection_name = cls._get_collection_name()
# Get max document limit and max byte size from meta.
max_size = cls._meta.get('max_size') or 10 * 2 ** 20 # 10MB default
max_documents = cls._meta.get('max_documents')
# MongoDB will automatically raise the size to make it a multiple of
# 256 bytes. We raise it here ourselves to be able to reliably compare
# the options below.
if max_size % 256:
max_size = (max_size // 256 + 1) * 256
# If the collection already exists and has different options
# (i.e. isn't capped or has different max/size), raise an error.
if collection_name in db.collection_names():
collection = db[collection_name]
options = collection.options()
if (
options.get('max') != max_documents or
options.get('size') != max_size
):
raise InvalidCollectionError(
'Cannot create collection "{}" as a capped '
'collection as it already exists'.format(cls._collection)
)
return collection
# Create a new capped collection.
opts = {'capped': True, 'size': max_size}
if max_documents:
opts['max'] = max_documents
return db.create_collection(collection_name, **opts)
def to_mongo(self, *args, **kwargs):
data = super(Document, self).to_mongo(*args, **kwargs)

View File

@@ -608,9 +608,9 @@ class EmbeddedDocumentField(BaseField):
"""
def __init__(self, document_type, **kwargs):
if (
not isinstance(document_type, six.string_types) and
not issubclass(document_type, EmbeddedDocument)
if not (
isinstance(document_type, six.string_types) or
issubclass(document_type, EmbeddedDocument)
):
self.error('Invalid embedded document class provided to an '
'EmbeddedDocumentField')