rework validation documentation based on review
This commit is contained in:
		| @@ -426,19 +426,6 @@ either a single field name, or a list or tuple of field names:: | |||||||
|         first_name = StringField() |         first_name = StringField() | ||||||
|         last_name = StringField(unique_with='first_name') |         last_name = StringField(unique_with='first_name') | ||||||
|  |  | ||||||
| Skipping Document validation on save |  | ||||||
| ------------------------------------ |  | ||||||
| You can also skip the whole document validation process by setting |  | ||||||
| ``validate=False`` when calling the :meth:`~mongoengine.document.Document.save` |  | ||||||
| method:: |  | ||||||
|  |  | ||||||
|     class Recipient(Document): |  | ||||||
|         name = StringField() |  | ||||||
|         email = EmailField() |  | ||||||
|  |  | ||||||
|     recipient = Recipient(name='admin', email='root@localhost') |  | ||||||
|     recipient.save()               # will raise a ValidationError while |  | ||||||
|     recipient.save(validate=False) # won't |  | ||||||
|  |  | ||||||
| Document collections | Document collections | ||||||
| ==================== | ==================== | ||||||
|   | |||||||
| @@ -41,35 +41,6 @@ already exist, then any changes will be updated atomically.  For example:: | |||||||
| .. seealso:: | .. seealso:: | ||||||
|     :ref:`guide-atomic-updates` |     :ref:`guide-atomic-updates` | ||||||
|  |  | ||||||
| Pre save data validation and cleaning |  | ||||||
| ------------------------------------- |  | ||||||
| MongoEngine allows you to create custom cleaning rules for your documents when |  | ||||||
| calling :meth:`~mongoengine.Document.save`.  By providing a custom |  | ||||||
| :meth:`~mongoengine.Document.clean` method you can do any pre validation / data |  | ||||||
| cleaning. |  | ||||||
|  |  | ||||||
| This might be useful if you want to ensure a default value based on other |  | ||||||
| document values for example:: |  | ||||||
|  |  | ||||||
|     class Essay(Document): |  | ||||||
|         status = StringField(choices=('Published', 'Draft'), required=True) |  | ||||||
|         pub_date = DateTimeField() |  | ||||||
|  |  | ||||||
|         def clean(self): |  | ||||||
|             """Ensures that only published essays have a `pub_date` and |  | ||||||
|             automatically sets `pub_date` if essay is published and `pub_date` |  | ||||||
|             is not set""" |  | ||||||
|             if self.status == 'Draft' and self.pub_date is not None: |  | ||||||
|                 msg = 'Draft entries should not have a publication date.' |  | ||||||
|                 raise ValidationError(msg) |  | ||||||
|             # Set the pub_date for published items if not set. |  | ||||||
|             if self.status == 'Published' and self.pub_date is None: |  | ||||||
|                 self.pub_date = datetime.now() |  | ||||||
|  |  | ||||||
| .. note:: |  | ||||||
|     Cleaning is only called if validation is turned on and when calling |  | ||||||
|     :meth:`~mongoengine.Document.save`. |  | ||||||
|  |  | ||||||
| Cascading Saves | Cascading Saves | ||||||
| --------------- | --------------- | ||||||
| If your document contains :class:`~mongoengine.fields.ReferenceField` or | If your document contains :class:`~mongoengine.fields.ReferenceField` or | ||||||
|   | |||||||
| @@ -3,10 +3,11 @@ Document Validation | |||||||
| ==================== | ==================== | ||||||
|  |  | ||||||
| By design, MongoEngine strictly validates the documents right before they are inserted in MongoDB | By design, MongoEngine strictly validates the documents right before they are inserted in MongoDB | ||||||
| and make sure they are consistent with the fields defined in your models. | and makes sure they are consistent with the fields defined in your models. | ||||||
|  |  | ||||||
| Mongoengine will not validate a document when an object is loaded from the DB into an instance | MongoEngine makes the assumption that the documents that exists in the DB are compliant with the schema. | ||||||
| of your model but this operation will fail under some circumstances (e.g. if there is a field in | This means that Mongoengine will not validate a document when an object is loaded from the DB into an instance | ||||||
|  | of your model but this operation may fail under some circumstances (e.g. if there is a field in | ||||||
| the document fetched from the database that is not defined in your model). | the document fetched from the database that is not defined in your model). | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -53,23 +54,28 @@ The following feature can be used to customize the validation: | |||||||
|  |  | ||||||
| * Document `clean` method | * Document `clean` method | ||||||
|  |  | ||||||
| Although not its primary use case, `clean` may be use to do validation that involves multiple fields. | This method is called as part of :meth:`~mongoengine.document.Document.save` and should be used to provide | ||||||
| Note that `clean` runs before the validation when you save a Document. | custom model validation and/or to modify some of the field values prior to validation. | ||||||
|  | For instance, you could use it to automatically provide a value for a field, or to do validation | ||||||
|  | that requires access to more than a single field. | ||||||
|  |  | ||||||
| .. code-block:: python | .. code-block:: python | ||||||
|  |  | ||||||
|     class Person(Document): |     class Essay(Document): | ||||||
|         first_name = StringField() |         status = StringField(choices=('Published', 'Draft'), required=True) | ||||||
|         last_name = StringField() |         pub_date = DateTimeField() | ||||||
|  |  | ||||||
|         def clean(self): |         def clean(self): | ||||||
|             if self.first_name == 'John' and self.last_name == 'Doe': |             # Validate that only published essays have a `pub_date` | ||||||
|                 raise ValidationError('John Doe is not a valid name') |             if self.status == 'Draft' and self.pub_date is not None: | ||||||
|  |                 raise ValidationError('Draft entries should not have a publication date.') | ||||||
|     Person(first_name='Billy', last_name='Doe').save() |             # Set the pub_date for published items if not set. | ||||||
|     Person(first_name='John', last_name='Doe').save()      # raises ValidationError (John Doe is not a valid name) |             if self.status == 'Published' and self.pub_date is None: | ||||||
|  |                 self.pub_date = datetime.now() | ||||||
|  |  | ||||||
|  | .. note:: | ||||||
|  |     Cleaning is only called if validation is turned on and when calling | ||||||
|  |     :meth:`~mongoengine.Document.save`. | ||||||
|  |  | ||||||
| * Adding custom Field classes | * Adding custom Field classes | ||||||
|  |  | ||||||
| @@ -98,19 +104,20 @@ to subclass a Field and encapsulate some validation by overriding the `validate` | |||||||
|    When overriding `validate`, use `self.error("your-custom-error")` instead of raising ValidationError explicitly, |    When overriding `validate`, use `self.error("your-custom-error")` instead of raising ValidationError explicitly, | ||||||
|    it will provide a better context with the error message |    it will provide a better context with the error message | ||||||
|  |  | ||||||
| Disabling validation | Skipping validation | ||||||
| ==================== | ==================== | ||||||
|  |  | ||||||
| We do not recommend to do this but if for some reason you need to disable the validation of a document | Although discouraged as it allows to violate fields constraints, if for some reason you need to disable | ||||||
| when you call `.save()`, you can use `.save(validate=False)`. | the validation and cleaning of a document when you call `.save()`, you can use `.save(validate=False)`. | ||||||
|  |  | ||||||
| .. code-block:: python | .. code-block:: python | ||||||
|  |  | ||||||
|     class Person(Document): |     class Person(Document): | ||||||
|         age = IntField() |         age = IntField(max_value=100) | ||||||
|  |  | ||||||
|     Person(age='garbage').save()    # raises ValidationError (garbage could not be converted to int: ['age']) |     Person(age=1000).save()    # raises ValidationError (Integer value is too large) | ||||||
|  |  | ||||||
|     Person(age='garbage').save(validate=False) |     Person(age=1000).save(validate=False) | ||||||
|     person = Person.objects.first() |     person = Person.objects.first() | ||||||
|     assert person.age == 'garbage' |     assert person.age == 1000 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -314,7 +314,8 @@ class BaseDocument: | |||||||
|  |  | ||||||
|     def clean(self): |     def clean(self): | ||||||
|         """ |         """ | ||||||
|         Hook for doing document level data cleaning before validation is run. |         Hook for doing document level data cleaning (usually validation or assignment) | ||||||
|  |         before validation is run. | ||||||
|  |  | ||||||
|         Any ValidationError raised by this method will not be associated with |         Any ValidationError raised by this method will not be associated with | ||||||
|         a particular field; it will have a special-case association with the |         a particular field; it will have a special-case association with the | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user