MongoEngine – Working with EnumField

Updated: February 9, 2024 By: Guest Contributor Post a comment

Overview

In this tutorial, we delve into the use of the EnumField in MongoEngine, a Document-Object Mapper (DOM) for working with MongoDB from Python. Utilizing enums can enhance the readability and stability of your code by ensuring that only a predefined set of values can be assigned to fields. We’ll start with the basics and gradually move to more advanced topics, providing code examples at each step.

Setting Up Your Environment

Before diving into the specifics of working with EnumField, ensure your environment is set up correctly. Install MongoEngine via pip:

pip install mongoengine

Make sure MongoDB is running on your machine or connect to an existing MongoDB instance in your network.

Basic Usage of EnumField

To begin, let’s define a simple model with an EnumField. Enums in Python are defined using the enum module introduced in Python 3.4. Here’s how to utilize EnumField in your document definition:

from mongoengine import Document, EnumField
from enum import Enum
class UserRole(Enum):
    ADMIN = 'admin'
    USER = 'user'

class User(Document):
    role = EnumField(UserRole, default=UserRole.USER)

In the example above, we’ve defined an enum UserRole with two possible values, ADMIN and USER, and used it in our User model. This way, the role field can only hold values defined in the UserRole enum, enhancing data integrity.

Manipulating Documents with EnumField

Now that we have our model, let’s see how to create, update, and query documents. Creating a new document with an enum value is straightforward:

user = User(role=UserRole.ADMIN).save()
print(user.role)
# Output: UserRole.ADMIN

Updating a document to change its role is equally simple:

user.role = UserRole.USER
user.save()
print(user.role)
# Output: UserRole.USER

To query documents by their role, use the following syntax:

admin_users = User.objects(role=UserRole.ADMIN)
print(admin_users.count())
# Expected output: Number of users with the role of ADMIN

Advanced Enum Usages

Python’s enums are versatile and can be extended in various ways. One interesting approach is to add methods to your enums:

class UserRole(Enum):
    ADMIN = 'admin'
    USER = 'user'

    @classmethod
    def is_admin(cls, role):
        return role == cls.ADMIN

This method allows you to incorporate logic directly related to the enumeration, which can be handy in different parts of your application:

if UserRole.is_admin(user.role):
    print("User is an admin.")
# Expected output: User is an admin.

Another advanced feature is utilizing enum values with additional attributes. For instance, you might associate a user-friendly name or description with your enum values:

class UserRole(Enum):
    ADMIN = ('admin', 'Site Administrator')
    USER = ('user', 'Regular User')

    def __init__(self, code, description):
        self.code = code
        self.description = description

    @property
    def info(self):
        return f'{self.description} ({self.code})'

With this approach, your enum carries more meaningful data that can be used throughout your application:

print(UserRole.ADMIN.info)
# Output: Site Administrator (admin)

Conclusion

The use of EnumField in MongoEngine documents promotes type safety and clarifies the possible values for fields, leading to cleaner, more maintainable code. By exploring both basic and advanced features, we’ve seen how enums can be a powerful ally in designing robust data models. These examples only scratch the surface, and there’s much more to discover about both MongoEngine and Python’s enum module.