Models
Django ORM base models
- class smarter.lib.django.models.TimestampedModel(*args, **kwargs)[source]
Abstract base model for all Django ORM models in the Smarter project, providing automatic timestamp fields and utility methods.
This class should be used as the base class for all models in the project to ensure consistent tracking of creation and modification times. It adds
created_atandupdated_atfields, and provides validation and time-difference utilities.Example Usage:
from smarter.smarter.lib.django.models import TimestampedModel class MyModel(TimestampedModel): name = models.CharField(max_length=100) # Creating an instance obj = MyModel.objects.create(name="Example") print(obj.created_at) # Timestamp of creation print(obj.updated_at) # Timestamp of last update # Checking elapsed time since last update seconds = obj.elapsed_updated() print(f"Seconds since last update: {seconds}")
Parameters:
Inherits all parameters from
django.db.models.Model.Note
This class is abstract and will not create a database table by itself.
The
validate()method is a stub and should be implemented in subclasses as needed.The
save()method enforces validation before saving, raising a detailed error if validation fails.
Important
If you override
save(), ensure you callsuper().save(*args, **kwargs)to retain validation and timestamp behavior.The
elapsed_updatedproperty expectsupdated_atto be set; if not, it returnsNone.Passing a non-datetime object to
elapsed_updatedwill raise aTypeError.The hashed ID methods provide a way to encode and decode object IDs for use in URLs in cases where you want to avoid exposing raw database IDs.
- Parameters:
created_at (Unknown) –
Created at
Timestamp indicating when the model instance was created. This field is automatically set to the current date and time when the instance is first created. It is indexed in the database for efficient querying.
updated_at (Unknown) –
Updated at
Timestamp indicating when the model instance was last updated. This field is automatically updated to the current date and time whenever the instance is saved. It is indexed in the database for efficient querying.
- HASH_FLOOR = 1000000
- HASH_PREFIX = 'r'
- HASH_SUFFIX = 'x'
- cache_expiration = 60
- created_at
-
Created at
Timestamp indicating when the model instance was created. This field is automatically set to the current date and time when the instance is first created. It is indexed in the database for efficient querying.
- Type:
Type
- property elapsed_updated: int | None
Calculate the absolute time difference in seconds between a given datetime and the model’s
updated_attimestamp.This property is useful for determining how much time has elapsed since the model instance was last updated, or for comparing the
updated_atfield to any arbitrary datetime.Parameters:
dt (datetime, optional): The reference datetime to compare against
updated_at. - Ifdtis not provided, the current time is used. - Both naive and timezone-aware datetime objects are supported; the method will handle conversions as needed.
Returns:
int or None: The absolute difference in seconds between
updated_atanddt. ReturnsNoneifupdated_atis not set.
Example Usage:
obj = MyModel.objects.get(pk=1) # Time since last update seconds = obj.elapsed_updated print(f"Seconds since last update: {seconds}") # Compare to a specific datetime import datetime dt = datetime.datetime(2025, 12, 1, 12, 0, 0) diff = obj.elapsed_updated(dt) print(f"Seconds between updated_at and 2025-12-01 12:00:00: {diff}")
Note
Handles both naive and aware datetime objects, converting as necessary to ensure accurate calculation.
If
updated_atis not set (e.g., the object has not been saved), returnsNone.
Attention
If
dtis provided and is not adatetime.datetimeinstance, aTypeErrorwill be raised.Always ensure that
updated_atis set before relying on this property for calculations.
- classmethod find_hash(value)[source]
Finds and returns the first substring in the given value that matches the hashed ID format.
- classmethod get_cached_object(invalidate=False, pk=None)[source]
Retrieve a model instance by primary key, using caching to optimize performance. This method is selectively overridden in models that inherit from TimestampedModel to provide class-specific function parameters.
Example usage:
# Retrieve by primary key instance = MyModel.get_cached_object(pk=1)
- classmethod get_cached_objects(invalidate=False)[source]
Retrieve model instances using caching to optimize performance. This method is selectively overridden in models that inherit from TimestampedModel to provide class-specific function parameters.
Example usage:
# Retrieve all instances instances = MyModel.get_cached_objects()
- classmethod get_object_by_locator(locator)[source]
Retrieves an object based on its record locator.
Example:
obj = MyModel.objects.create() print(obj.id) # e.g., 123 locator = obj.record_locator # e.g., "mymodel-rc2x" retrieved_obj = MyModel.get_object_by_locator(locator) print(type(retrieved_obj)) # Should be <class 'MyModel'> print(retrieved_obj) # Should be the same as obj
- Parameters:
locator (
str) – The record locator string to decode and search for.- Returns:
The model instance if found, otherwise None.
- Return type:
- classmethod hash_regex()[source]
Returns a regex pattern that matches the hashed ID format for this model anywhere in a string.
The hashed ID format is defined by the
HASH_PREFIXandHASH_SUFFIXclass attributes, with a base64-encoded string in between. This regex can be used to validate or extract hashed IDs from strings, including when embedded in URLs.- Returns:
A regex pattern for matching hashed IDs.
- Return type:
- property hashed_id: str[source]
Returns a URL-friendly hashed version of the object’s ID for use in URLs and other contexts where an obscured, non-identifying, non-sequential identifier is preferred.
Encoding scheme: 1. Take the object’s ID and add a large constant (HASH_FLOOR) to ensure it’s not easily guessable. 2. Convert the resulting number to a string and encode it using URL-safe base64 encoding. 3. Remove any padding characters from the encoded string. 4. Add a prefix and suffix to the encoded string to create a recognizable format.
Example:
obj = MyModel.objects.create() print(obj.id) # e.g., 123 print(obj.hashed_id) # e.g., "rc2x"
- Returns:
Hashed ID string (URL-safe, no padding)
- Return type:
- classmethod id_from_hashed_id(hashed_id)[source]
Decodes a hashed ID back to the original object ID.
decoding scheme: 1. Validate that the hashed ID starts with the expected prefix and ends with the expected suffix. 2. Remove the prefix and suffix to isolate the base64-encoded string. 3. Add padding if necessary to make the length of the encoded string a multiple of 4. 4. Decode the base64 string to get the original number as a string. 5. Convert the decoded string to an integer and subtract the HASH_FLOOR to get the original ID.
Example:
my_record = MyModel.objects.create() print(my_record.id) # e.g., 123 hashed_id = my_record.hashed_id # e.g., "rc2x" original_id = MyModel.id_from_hashed_id(hashed_id) print(original_id) # Should print the original ID (e.g., 123)
- property record_locator: str[source]
Returns a short, URL-friendly record locator derived from the object’s ID.
Example:
obj = MyModel.objects.create(name="Example") print(obj.id) # e.g., 123 print(obj.record_locator) # e.g., "chatbot-rc2x"
- Returns:
Record locator string (URL-safe, no padding)
- Return type:
- save(*args, **kwargs)[source]
Save the model instance to the database, performing validation before the actual save.
This method overrides the default
save()behavior of Django models to ensure that the model is validated by callingvalidate()before any data is written to the database. If validation fails, adjango.core.exceptions.ValidationErroris raised with detailed information about the error, the arguments passed, the model class, and the current field values.- Parameters:
*args – Positional arguments passed to the parent
save()method. These are forwarded to Django’s ORM.**kwargs – Keyword arguments passed to the parent
save()method. These are forwarded to Django’s ORM.
Examples
obj = MyModel(name="Example") obj.save() # Will call validate() before saving
Note
The
validate()method is intended to be overridden in subclasses to provide custom validation logic.If
validate()raises aValidationError, the save operation is aborted and the error is propagated.The error message includes the arguments, keyword arguments, model class, and current field values for easier debugging.
Important
If you override this method in a subclass, always call
super().save(*args, **kwargs)to retain validation and timestamp functionality.If validation fails, no data will be saved to the database.
- to_json()[source]
Serialize the model instance to a JSON-compatible dictionary.
This method uses the custom
SmarterJSONEncoderto ensure that all fields, including timestamps and any complex data types, are properly serialized.
- updated_at
-
Updated at
Timestamp indicating when the model instance was last updated. This field is automatically updated to the current date and time whenever the instance is saved. It is indexed in the database for efficient querying.
- Type:
Type