Skip to content

Model Mixins

models

TimeStampedModel

Bases: TimeStampedModelOnly, MonitorChangeMixin

Abstract base model with timestamps and field change monitoring.

Combines TimeStampedModelOnly (created/modified fields + admin URL helpers) with MonitorChangeMixin (field change callbacks). This is the recommended base class for most application models.

Example
class Person(TimeStampedModel):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    home_address = USAddressField(blank=True, null=True)
    roles = MultipleChoiceField(
        choices=[('Admin', 'Admin'), ('User', 'User')],
        null=True, blank=True, default=['Guest'],
    )

TimeStampedModelOnly

Bases: ModelUtilsMixin, Model

Abstract base model with automatic created and modified timestamps.

Inherits admin URL helpers from ModelUtilsMixin but does not include change monitoring. Use TimeStampedModel if you also need field change callbacks.

Attributes:

Name Type Description
created

Auto-set to the current time when the object is first saved.

modified

Auto-updated to the current time on every save.

Example
class AuditLog(TimeStampedModelOnly):
    action = models.CharField(max_length=200)

ModelUtilsMixin

Mixin providing Django admin URL helpers for model instances and classes.

Adds class methods and instance methods/properties for generating admin URLs (add, change, changelist, delete) without manually constructing URL patterns. Also provides original_obj for comparing field changes and a change_link property for rendering clickable admin links.

Example
class Person(ModelUtilsMixin):
    name = models.CharField(max_length=100)

# Class-level URLs
Person.get_add_url()           # /admin/myapp/person/add/
Person.get_changelist_url()    # /admin/myapp/person/
Person.get_change_url(pk=1)    # /admin/myapp/person/1/change/

# Instance-level
person = Person.objects.get(pk=1)
person.get_obj_change_url()    # /admin/myapp/person/1/change/
person.change_link             # HTML <a> tag linking to change page

GenericRelationMixin

Bases: Model

Mixin for models using Django's generic relations (ContentType framework).

Provides convenience class methods and properties for querying related objects through content types without manually constructing ContentType filters.

Subclasses must define content_type (ForeignKey to ContentType) and object_id fields, typically via GenericForeignKey.

Example
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType

class Comment(GenericRelationMixin):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    text = models.TextField()

# Query comments for a specific object
comments = Comment.for_object(my_article)

for_object(obj) classmethod

Return queryset filtered to a specific object instance.

Parameters:

Name Type Description Default
obj

The model instance to filter by (matches both content type and ID).

required

Returns:

Type Description

QuerySet of records related to the given object.

for_objects(objs) classmethod

Return queryset filtered to multiple object instances of the same type.

Parameters:

Name Type Description Default
objs

List of model instances (must all be the same model type).

required

Returns:

Type Description

QuerySet of records related to any of the given objects, or None if

the list is empty.

for_object_type(obj) classmethod

Return queryset filtered to all records for an object's model type.

Parameters:

Name Type Description Default
obj

A model instance whose type is used to determine the content type.

required

Returns:

Type Description

QuerySet of all records matching the content type of the given object.

for_model(model) classmethod

Return queryset filtered to all records for a given model class.

Parameters:

Name Type Description Default
model

A Django model class.

required

Returns:

Type Description

QuerySet of all records matching the content type of the given model.

MonitorChangeMixin

Mixin that fires callbacks when monitored field values change on save.

Set monitor_fields to a list of (field_name, options) tuples. Each options dict may contain a callback that receives the instance, old value, and new value whenever the field changes.

Requires original_obj (provided by ModelUtilsMixin) to compare pre-save and post-save values.

Attributes:

Name Type Description
monitor_fields

List of tuples defining which fields to watch and their callbacks.

Example
class Order(TimeStampedModel):
    status = models.CharField(max_length=20)

    monitor_fields = [
        ('status', {
            'callback': lambda self, old, new: print(
                f"Order {self.pk} status: {old} -> {new}"
            )
        }),
    ]

    def save(self, **kwargs):
        super().save(**kwargs)
        self.notify_changes()