Insert documents into MongoDB

Insert a Document

Creating records in Djongo begins with defining your data models inside an app’s models.py — each model class becomes a collection with fields representing MongoDB fields. You can call Model.objects.create(field1=value1, field2=value2) to make and save a new object in one step, or instantiate an object and invoke .save() if you need to tweak attributes before storage.

Once models are in place, Django’s admin site can be used for data creation — the admin UI lets you fill in fields via a form interface, while the interactive shell (python manage.py shell) lets you write ODM methods directly. Behind the scenes, Djongo turns your method calls into database inserts without you writing any pymongo queries.

For safer entry creation where duplication must be avoided, Djongo provides get_or_create() which attempts retrieval based on the given lookup fields and creates a new record only if none exists.

Djongo helps you focus on what data you want to store rather than how it gets stored. More information on inserting methods can be found in the Django queryset reference

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

The following pymongo command is generated:

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

The two steps of instance creation followed by a save() can be shortened to one line 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

The following pymongo command is generated:

db['myapp_entry'].insert_many(
    [{'headline': 'h1', 'blog': { 'name': 'Paul', 'content': 'How to sing' }}],
    ordered=False)
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

A commandline traceback exception is raised on running main.

$ python manage.py main

...
    raise ValidationError(errors)
django.core.exceptions.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': 'Paul',
                    'tagline': {
                        'title': 'Tagline Title',
                        'subtitle': 'Tagline Subtitle'
                    }
                })
copy code

The following pymongo command is generated:

db['myapp_entry'].insert_many(
    [{'headline': 'h1', 'blog': {
                    'name': 'Paul',
                    'tagline': {
                        'title': 'Tagline Title',
                        'subtitle': 'Tagline Subtitle'
                    }
                }}],
    ordered=False)
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

The following pymongo command is generated:

db['myapp_entry'].insert_many(
    [{'headline': 'h1', 'authors': [{'name': 'John', 'email': 'john@mail.com'},
                                    {'name': 'Paul', 'email': 'paul@mail.com'}]}],
    ordered=False)
copy code