Sling Academy
Home/Python/MongoEngine – Working with EnumField

MongoEngine – Working with EnumField

Last updated: February 09, 2024

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.

Next Article: MongoEngine – Using ImageField and FileField

Previous Article: MongoEngine: Working with ListField

Series: Data Persistence in Python – Tutorials & Examples

Python

You May Also Like

  • Python Warning: Secure coding is not enabled for restorable state
  • Python TypeError: write() argument must be str, not bytes
  • 4 ways to install Python modules on Windows without admin rights
  • Python TypeError: object of type ‘NoneType’ has no len()
  • Python: How to access command-line arguments (3 approaches)
  • Understanding ‘Never’ type in Python 3.11+ (5 examples)
  • Python: 3 Ways to Retrieve City/Country from IP Address
  • Using Type Aliases in Python: A Practical Guide (with Examples)
  • Python: Defining distinct types using NewType class
  • Using Optional Type in Python (explained with examples)
  • Python: How to Override Methods in Classes
  • Python: Define Generic Types for Lists of Nested Dictionaries
  • Python: Defining type for a list that can contain both numbers and strings
  • Using TypeGuard in Python (Python 3.10+)
  • Python: Using ‘NoReturn’ type with functions
  • Type Casting in Python: The Ultimate Guide (with Examples)
  • Python: Using type hints with class methods and properties
  • Python: Typing a function with default parameters
  • Python: Typing a function that can return multiple types