Insert documents into MongoDB

Insert a Single Document

Inserting documents into MongoDB can be done using either the save() or create() methods. Use save() when there is a need to fill the model fields at separate parts of the code.

models.py

from djongo import models

class Entry(models.Model):
    _id = models.ObjectIdField()
    headline = models.CharField(max_length=255)
copy code

Then, in myapp/management/commands/main.py write:

main.py

from django.core.management.base import BaseCommand
from models import Entry

class Command(BaseCommand):
    help = "Main execution file"

    def handle(self, *args, **options):
        entry = Entry(headline='h1')
        entry.save()
        self.stdout.write(self.style.SUCCESS('Main executed'))
copy code

Next, in the command line execute:

python manage.py main
copy code

This generates the following pymongo command:

db['myapp_entry'].insert_many(
    [{'headline': 'h1'}],
    ordered=False)
copy code

This can be further shortened using the create() method.

main.py

from django.core.management.base import BaseCommand
from models import Entry

class Command(BaseCommand):
    help = "Main execution file"

    def handle(self, *args, **options):
        entry = Entry.objects.create(headline='h2')
        self.stdout.write(self.style.SUCCESS('Main executed'))
copy code

EmbeddedField

MongoDB allows the creation of an embedded document. You can include another model in the parent model through the EmbeddedField.

models.py

from djongo import models

class Blog(models.Model):
    name = models.CharField(max_length=100)
    content = models.TextField()

    class Meta:
        abstract = True

class Entry(models.Model):
    _id = models.ObjectIdField()
    blog = models.EmbeddedField(
        model_container=Blog
    )
    headline = models.CharField(max_length=255)
copy code

Describe the contents of the EmbeddedField using a dict.

main.py

from django.core.management.base import BaseCommand
from models import Entry

class Command(BaseCommand):
    help = "Main execution file"

    def handle(self, *args, **options):
        entry = Entry.objects.create(
                        headline='h1',
                        blog={ 'name': 'Paul', 'content': 'How to sing' }
                )
copy code

Field data integrity checks

Djongo automatically validates the value assigned to an EmbeddedField. Integrity criteria (null=True or blank=False) can be applied on the ÈmbeddedField or to the internal fields (CharField)

models.py

from djongo import models

class Entry(models.Model):
    _id = models.ObjectIdField()
    blog = models.EmbeddedField(
        model_container=Blog,
        null=True
    )
    headline = models.CharField(max_length=255)
copy code

main.py

from django.core.management.base import BaseCommand
from models import Entry

class Command(BaseCommand):
    help = "Main execution file"

    def handle(self, *args, **options):
        e = Entry(headline='h1', blog=None)
        e.clean_fields()
copy code
$ python manage.py main
copy code

Works perfectly with no validation errors. Next, set null=False under the EmbeddedField:

models.py

from djongo import models

class Entry(models.Model):
    _id = models.ObjectIdField()
    blog = models.EmbeddedField(
        model_container=Blog,
        null=False
    )
    headline = models.CharField(max_length=255)
copy code

main.py

from django.core.management.base import BaseCommand
from models import Entry

class Command(BaseCommand):
    help = "Main execution file"

    def handle(self, *args, **options):
        e = Entry(headline='h1', blog=None)
        e.clean_fields()
copy code
$ python manage.py main

ValidationError({'blog': ['This field cannot be null.']})
copy code

Nesting Embedded Fields

An EmbeddedField or ArrayField can be nested inside an EmbeddedField.

models.py

from djongo import models

class Tagline(models.Model):
    title = models.CharField(max_length=100)
    subtitle = models.CharField(max_length=100)

    class Meta:
        abstract = True

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.EmbeddedField(model_container=Tagline)

    class Meta:
        abstract = True

class Entry(models.Model):
    _id = models.ObjectIdField()
    blog = models.EmbeddedField(
        model_container=Blog
    )
    headline = models.CharField(max_length=255)
copy code

main.py

from django.core.management.base import BaseCommand
from models import Entry

class Command(BaseCommand):
    help = "Main execution file"

    def handle(self, *args, **options):
        e = Entry.objects.create(
                headline='h1',
                blog={
                    'name': 'b1',
                    'tagline': {
                        'title': 'Tagline Title',
                        'subtitle': 'Tagline Subtitle'
                    }
                })
copy code

Array fields

A model with an ArrayField is created as follows:

models.py

from djongo import models
from django import forms

class Author(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()

    class Meta:
        abstract = True


class Entry(models.Model):
    headline = models.CharField(max_length=255)    
    authors = models.ArrayField(
        model_container=Author,
    )
copy code

main.py

from django.core.management.base import BaseCommand
from models import Entry

class Command(BaseCommand):
    help = "Main execution file"

    def handle(self, *args, **options):
        entry = Entry(headline='h1')
        entry.authors = [{'name': 'John', 'email': 'john@mail.com'},
                        {'name': 'Paul', 'email': 'paul@mail.com'}]
        entry.save()
copy code

CollectionConstraint and Capped Collections

Djongo introduces a new CollectionConstraint. Use this to specify MongoDB specific collection properties that are usually used when calling create_collection

class CollectionConstraint:
    def __init__(self,
                 **kwargs):
copy code

All arguments passed to create_collection except for name can be used to create the CollectionConstraint instance. Valid arguments include, but are not limited to those described below

Arguments

ArgumentTypeDescription
codec_optionsCodecOptionsAn instance of CodecOptions.
collationCollationTakes an instance of Collation

Example

models.py

from djongo.models import CollectionConstraint
from djongo import models
from pymongo.read_concern import ReadConcern

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    class Meta:
        constraints = [
            CollectionConstraint(
                read_concern=ReadConcern(level='majority'),
                capped=True,
                max=100
            )
        ]
copy code

Schema Validation and CheckConstraint

Djongo automatically generates schema validation JSON documents for your models providing an extra layer of data validation and checking from within MongoDB. By creating check constraints in the Model Meta definition, djongo automatically interprets it to generate a JSON Schema and a query expression

models.py

from djongo.models import CheckConstraint, Q
from djongo import models
from pymongo.read_concern import ReadConcern

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()
    author_age = models.IntegerField()

    class Meta:
        constraints = [
             CheckConstraint(check=Q(author_age__gte=18), name='age_gte_18')
        ]
copy code