Models & Migrations
Maybern uses Django’s ORM with custom base classes and field types. This guide covers model design patterns and migration best practices.Base Model Classes
All models should inherit from one of these base classes:TimeStampedModel
Base model with
created_at and updated_at fields. Use for non-tenant-specific data.CustomerTimeStampedModel
Adds
customer_id for multi-tenancy. Use for all tenant-specific models.AuditableModel
Enables audit logging via the DB manager. Use when you need change tracking.
VersionModel
For type-2 versioning (maintaining historical records). Use for versioned entities.
Model Example
Custom Field Types
All ORM fields are wrapped inserver.apps.core.models.fields:
| Field Type | Description |
|---|---|
MUUIDField | UUID with prefix (e.g., INVS_abc123) |
TextModelField | Text field with standard validation |
ForeignKeyModelField | Foreign key with sensible defaults |
DecimalModelField | Decimal with precision settings |
DateModelField | Date field |
BooleanModelField | Boolean field |
Benefits of Wrapped Fields
- Automatic conversion to dataclass fields
- Built-in validation
- Consistent defaults across the codebase
- Custom serialization behavior
Field Decorators
Special decorators for sensitive data:- @sensitive
- @encrypt
Marks a field as containing sensitive data:Sensitive fields are:
- Automatically converted to
SecureString - Excluded from logs
- Masked in error messages
Model Managers and QuerySets
Managers
Custom managers wrap ORM functionality:QuerySets
Custom querysets provide read query overrides:Versioned Models
For entities that need historical tracking (type-2 models):- Parent model with current state
- Version model with historical records
- Automatic version management
Constraints
Custom constraints beyond Django’s built-in options:Migration Best Practices
1
Generate migrations
After modifying models:
2
Review the migration
Always review generated migrations for:
- Correct field types
- Index creation
- Data migrations needed
3
Run migrations locally
4
Test the migration
Ensure the migration:
- Runs without errors
- Is reversible (when possible)
- Handles existing data correctly
Data Migrations
For complex data changes, create a data migration:Model Design Principles
Focus on Data Structure
Focus on Data Structure
Models should only define:
- Fields and relationships
- Constraints and indexes
- Meta options
Use Appropriate Base Classes
Use Appropriate Base Classes
CustomerTimeStampedModelfor most tenant dataAuditableModelwhen you need change trackingVersionModelfor historical records
Define Clear Relationships
Define Clear Relationships
Always specify:
on_deletebehaviorrelated_namefor reverse lookupsnull=Truewhen optional
Add Proper Indexes
Add Proper Indexes
Create indexes for:
- Foreign key fields (automatic)
- Fields used in filters
- Fields used in ordering
- Unique constraint fields