Models and Fields
Models
A Model is the single, canonical source of information about the data your application stores. Models need to be defined and registered. Each attribute of the class represents a MongoDB document field. Each model maps to one MongoDB collection and encapsulates the structure and behavior of that collection in one place.
from djongo import models
class Entry(models.Model):
_id = models.ObjectIdField()
headline = models.CharField(max_length=255)
Typically, all models are defined inside the models.py file of an app.
Naming the definition file as models.py is not mandatory. However, a class is not recognized as model definition
unless it is a subclass of djongo.models.Model. A model is registered by registering the app it lives under.
For example, if the models for your application live in the module myapp.models
(the package structure that is created for an application by the manage.py startapp script),
INSTALLED_APPS should read, in part:
INSTALLED_APPS = [
# ...
"myapp.apps.MyappAppConfig",
# ...
]
More details regarding models can be found on the Django documentation.
Fields
The most important part of a model – and the only required part of a model – is the list of database fields it defines. Fields are specified by class attributes. Each field in a model should be an instance of an appropriate Field class.
Djongo automatically inherits and supports the following fields:
| Field Type | Description |
|---|---|
AutoField | An integer field that automatically increments and is used as the default primary key. |
BigAutoField | Like AutoField but stores larger integer values (64-bit). |
BigIntegerField | A 64-bit integer field. |
BinaryField | A field to store raw binary data. |
BooleanField | Stores True or False values. |
CharField | A string field for small-to-medium sized text; requires max_length. |
DateField | Stores a date (Python datetime.date). |
DateTimeField | Stores date and time (Python datetime.datetime). |
DecimalField | A fixed-precision decimal number field. |
DurationField | Stores a period of time (Python timedelta). |
EmailField | A CharField that validates input as an email address. |
FileField | A file-upload field; stores the file path. |
FilePathField | Stores the file path from the filesystem. |
FloatField | Stores floating-point numbers. |
ImageField | A FileField that validates uploaded images. |
IntegerField | A basic integer field. |
GenericIPAddressField | Stores IPv4 or IPv6 addresses. |
JSONField | Stores JSON-encoded data (dict/list). |
PositiveIntegerField | Like IntegerField but only allows non-negative values. |
PositiveSmallIntegerField | Like PositiveIntegerField but for smaller values. |
SmallIntegerField | Like IntegerField but for smaller values. |
SlugField | A CharField that only allows letters, numbers, hyphens or underscores. |
TextField | A large text field (no max_length required). |
TimeField | Stores a time (Python datetime.time). |
URLField | A CharField that validates input as a URL. |
UUIDField | Stores a universally unique identifier (uuid). |
| Relational Fields | Fields that define relationships between models |
ForeignKey | A many-to-one relationship; requires on_delete. |
ManyToManyField | A many-to-many relationship. |
OneToOneField | A one-to-one relationship; like a unique ForeignKey. |
Field options
Each instance of a Field can be instantiated with several options:
| Option | Description |
|---|---|
| null | Stores empty values as NULL in the database if True. Avoid on string fields if possible. Default: False. |
| blank | Allows the field to be blank at the form/validation level if True. Default: False. |
| choices | An iterable or mapping restricting the allowed set of values (renders a select widget). |
| db_column | Custom database column name for the field; defaults to the attribute name. |
| db_comment | Database comment for the column, useful for documentation. |
| db_default | A database-level default (literal or function). default still takes precedence in Python. |
| db_index | Creates a database index on the column if True. |
| db_tablespace | Database tablespace name for the field’s index. |
| default | Default value or callable (called for new instances). Cannot be mutable directly. |
| editable | If False, the field is excluded from admin and any ModelForm. Default: True. |
| error_messages | Override default error messages via a dict (keys like null, blank, invalid_choice, etc.). |
| help_text | Extra help text displayed with forms; not HTML-escaped automatically. |
| primary_key | If True, designates the field as the model’s primary key. Implies null=False and unique=True. |
| unique | Ensures the field value is unique across the table. |
| unique_for_date | Requires uniqueness with respect to a given date/datetime field’s date portion. |
| unique_for_month | Requires uniqueness with respect to the month portion of a date/datetime field. |
| unique_for_year | Requires uniqueness with respect to the year portion of a date/datetime field. |
| verbose_name | Human-readable field name (defaults to attribute name with underscores replaced by spaces). |
| validators | List of callables used to validate the field’s value. |
More details regarding fields can be found on the Django documentation.
MongoDB specific Fields
For working with MongoDB Djongo includes the EmbeddedField and ArrayField
Embedded Field
In MongoDB, you can create and store an embedded document.
Djongo lets you do the same by letting you include a child model
inside a parent model through the EmbeddedField.
from djongo import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = 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)
Nesting Embedded Fields
An EmbeddedField or an ArrayField can be nested inside an EmbeddedField.
There is no limitation on the depth of nesting.
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)
objects = models.DjongoManager()
API Reference
class EmbeddedField(MongoField):
def __init__(self,
model_container: typing.Type[Model],
model_form_class: typing.Type[forms.ModelForm] = None,
model_form_kwargs: dict = None,
*args, **kwargs):
Arguments
| Argument | Type | Description |
|---|---|---|
model_container | models.Model | The child model class type (not instance) that this embedded field will contain. |
model_form_class | models.forms.ModelForm | The child model form class type of the embedded model. |
model_form_kwargs | dict() | The kwargs (if any) that must be passed to the forms.ModelForm while instantiating it. |
Array Field
With MongoDB there can be an array of embedded documents inside the parent document. Djongo allows for the same feature by letting you embed an array of models, inside a parent model.
Example
from djongo import models
from django import forms
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
class Meta:
abstract = True
class BlogForm(forms.ModelForm):
class Meta:
model = Blog
fields = (
'name', 'tagline'
)
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
class Meta:
abstract = True
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = (
'name', 'email'
)
class Entry(models.Model):
blog = models.EmbeddedField(
model_container=Blog,
model_form_class=BlogForm
)
headline = models.CharField(max_length=255)
authors = models.ArrayField(
model_container=Author,
model_form_class=AuthorForm
)
objects = models.DjongoManager()
API Reference
class ArrayField(MongoField):
def __init__(self,
model_container: typing.Type[Model],
model_form_class: typing.Type[forms.ModelForm] = None,
model_form_kwargs: dict = None,
*args, **kwargs):
Arguments
| Argument | Type | Description |
|---|---|---|
model_container | models.Model | The child model class type (not the instance) that this array field will contain. |
model_form_class | models.forms.ModelForm | The child model form class type of the array model. All child models inside the array must be of the same type. Mixing different types of child models inside the embedded array is not supported. |
model_form_kwargs | dict() | The kwargs (if any) that must be passed to the forms.ModelForm while instantiating it. |
The ObjectId Field
For every document inserted into a collection MongoDB internally creates an ObjectID field with the name _id. Reference this field from within the Model:
class Entry(models.Model):
_id = models.ObjectIdField()
blog = models.EmbeddedField(
model_container=Blog,
)
By default, the ObjectIdField internally sets primary_key as True. This means the implicitly created id AUTOINCREMENT field will not be created. The Field inherits from the AutoField. An ObjectID will be automatically generated by MongoDB for every document inserted.
Consider using the ObjectIdField in your models if you want to avoid calling Django migrations every time you create a new model.
API Reference
class ObjectIdField(Field):
def __init__(self, *args, **kwargs):
Arguments
Same as the Field Base class
