Utilities
Cache
Clear cache
The function clear_cache()
wraps all the functionality needed to totally empty the django cache. Especially
convenient, if you put this function inside a management command, so you can flush the cache easily from the command
line:
# my_app/management/commands/clear_cache.py
from django.core.management.base import BaseCommand
from ai_django_core.utils import clear_cache
class Command(BaseCommand):
def handle(self, *args, **options):
clear_cache()
Date
DateHelper
The date helper class provides constants to use when querying for weekdays (“Monday”, “Tuesday”) with the django ORM.
The assignment from numbers to weekdays is not standarised throughout the different django packages. For example,
in the calendar
extension, Monday equals 0
, in the djang ORM, a Monday is represented by 2
.
To avoid using the integers directly, you can use the constants from this class as follows:
# Just get records where `my_date` is on a Sunday
MyModel.objects.filter(my_date__week_day=DateHelper.ORM_SUNDAY)
# Leave out records where `my_date` is on the weekend
MyModel.objects.exclude(my_date__week_day__in[DateHelper.ORM_SATURDAY, DateHelper.ORM_SUNDAY])
Add months
The function add_months(source_date)
provides a simple way to add any number of months to a given date:
from ai_django_core.utils import add_months
new_date = add_months(datetime.date(year=2020, month=9, day=19), 2)
# new_date = datetime.date(2020, 11, 19)
You can also use a negative number to subtract months.
Add days
The function add_days(source_date)
provides a simple way to add any number of months to a given date:
from ai_django_core.utils import add_days
new_date = add_days(datetime.date(year=2020, month=9, day=19), 2)
# new_date = datetime.date(2020, 9, 21)
You can also use a negative number to subtract days.
Add minutes
The function add_minutes(source_datetime)
provides a simple way to add any number of months to a given date:
from ai_django_core.utils import add_days
new_datetime = add_minutes(datetime.datetime(year=2020, month=9, day=19, hour=8), 60)
# new_datetime = add_minutes.date(2020, 9, 19, 9)
You can also use a negative number to subtract minutes.
Get next month
The function get_next_month()
is a wrapper for add_months()
and will return the current day one month later.
First day of month
The function first_day_of_month(source_date)
will return the first of month for any given date:
from ai_django_core.utils import first_day_of_month
new_date = first_day_of_month(datetime.date(year=2020, month=9, day=19))
# new_date = datetime.date(2020, 9, 1)
Format date to German format
The function get_formatted_date_str(source_date)
will return the string representation in the German format (“d.m.Y”):
from ai_django_core.utils import get_formatted_date_str
date_str = get_formatted_date_str(datetime.date(year=2020, month=9, day=19))
# date_str = "19.09.2020"
Create string representation of seconds
The function get_time_from_seconds(seconds)
will create a string representation of any (positive) number of seconds
in the format “HH:mm:ss”:
from ai_django_core.utils import get_formatted_date_str
time_str = get_time_from_seconds(3661)
# time_str = "01:01:01"
time_str = get_time_from_seconds(65)
# time_str = "00:01:05"
Format datetime objects timezone-aware
The function datetime_format(target_datetime, dt_format)
formats the given datetime according to the given format
with strftime
but takes the django timezone settings into account. If the timeszone cannot be interpreted, a fallback
without the timezone is used:
# settings.py
TIME_ZONE = 'Europe/Berlin'
# my_code.py
source_date = datetime.datetime(year=2020, month=6, day=26, hour=8, tzinfo=pytz.UTC)
datetime_str = datetime_format(source_date, '%d.%m.%Y %H:%M') # will return '26.06.2020 10:00'
Get start and end dates from calendar week
The function get_start_and_end_date_from_calendar_week(year, calendar_week)
provides a simple way to get the Monday
and Sunday of a given calendar week:
from ai_django_core.utils import get_start_and_end_date_from_calendar_week
monday, sunday = get_start_and_end_date_from_calendar_week(2020, 38)
# monday = datetime.date(2020, 09, 14); sunday = datetime.date(2020, 9, 20)
Get next calendar week
The function get_next_calendar_week(compare_date)
will return the the calendar week following the week of the given
compare_date
as an integer.
import datetime
from ai_django_core.utils import get_next_calendar_week
next_calendar_week = get_next_calendar_week(datetime.date(year=2020, month=9, day=19))
# next_calendar_week = 39
Get next weekday
The function next_weekday(given_date, weekday)
will return a date object of the next weekday following given_date
.
import calendar
import datetime
from ai_django_core.utils import next_weekday
next_friday = next_weekday(datetime.date(year=2020, month=9, day=19), calendar.FRIDAY)
# next_friday = datetime.date(year=2020, month=9, day=25)
Calculate the exact delta between to dates in months
The function date_month_delta(start_date, end_date)
calculates the number of months lying between two dates as
float. So from April 15th to May 1st it’s 0.5 months. Attention: The end_date
will be excluded in the result
(outer border).
import calendar
import datetime
from ai_django_core.utils import date_month_delta
months = date_month_delta(datetime.date(year=2020, month=8, day=1), datetime.date(year=2020, month=10, day=1))
# months = 2.0
Get the first and last date of a month
The function get_first_and_last_of_month()
returns the first and last date of a month as a Tuple.
The month is either the current month (if no date_object is passed), or the month of any date that is being passed.
Dates passed need to be datetime.date objects (not datetime.datetime)!
from ai_django_core.utils import get_first_and_last_of_month
# Today is 04.04.2022
first_of_month, last_of_month = get_first_and_last_of_month()
# first_of_month = datetime.date(day=1, month=4, year=2022)
# last_of_month = datetime.date(day=30, month=4, year=2022)
# Today is 02.06.2022
first_of_month, last_of_month = get_first_and_last_of_month(datetime(day=16, month=12, year=2022))
# first_of_month = datetime.date(day=1, month=12, year=2022)
# last_of_month = datetime.date(day=31, month=12, year=2022)
Get current date
The function tz_today()
will return the current date as an object. If timezone-awareness is enabled, the date
take it into consideration.
You can optionally use the argument str_format
, then the current date will be formatted in the given way and the
function will return a string. Please provide a strftime
-compatible value.
from ai_django_core.utils import next_weekday
# Here we'll get an object
current_date = tz_today()
# Here we'll get a string
current_date = tz_today('%d.%m.%Y')
Object ownership helper
The function log_whodid
provides a simple way to ensure object ownership is set correctly. Imagine, you have a model
which is derived from CommonInfo
:
from ai_django_core.models import CommonInfo
class MyModel(CommonInfo):
pass
You can now use the helper in any place where you have the user object available to set created_by
and lastmodified_by
like this:
def my_view(request, pk):
obj = MyModel.objects.get(pk=pk)
# Let the magic happen
log_whodid(obj, request.user)
...
Math
Round to decimal
The helper function round_to_decimal(value, precision)
will round a given value to a specific precision,
for example *.5. So 5.4 will be rounded to 5.5, and 5.6 to 5.5 as well. The result is always a float.
result = round_to_decimal(5.4, 0.5)
# result = 5.5
result = round_to_decimal(5.6, 0.5)
# result = 5.5
Round up decimal
The helper function round_up_decimal(value, precision)
will round a given value up to a specific precision,
for example *.5. So 5.4 will be rounded to 5.5, and 5.6 to 6 as well. The result is always a float.
result = round_up_decimal(5.4, 0.5)
# result = 5.5
result = round_up_decimal(5.6, 0.5)
# result = 6.0
Model
Convert object to dictionary
The function object_to_dict(obj, blacklisted_fields, include_id)
takes an instance of a django model and
extracts all attributes into a dictionary:
from django.db import models
class MyModel(models.Model):
value1 = models.IntegerField()
value2 = models.IntegerField()
....
obj = MyModel.objects.create(value_1=19, value_2=9)
result = object_to_dict(obj)
# result = {'value_1': 19, 'value_2': 9}
Optionally, fields can be excluded with the parameter blacklisted_fields
.
Passing a list of field names as string will prevent them from ending up in the result dictionary.
obj = MyModel.objects.create(value_1=19, value_2=9)
result = object_to_dict(obj, ['value_2'])
# result = {'value_1': 19}
By default the model ID is not part of the result. If you want to change this, pass include_id=True
to the function:
obj = MyModel.objects.create(value_1=19, value_2=9)
result = object_to_dict(obj, include_id=True)
# result = {'id': 1, value_1': 19, 'value_2': 9}
Named tuple
Named tuple helper
General
Factory function for quickly making a namedtuple suitable for use in a Django model as a choices attribute on a field. It will preserve order.
Here you’ll find a basic example:
class MyModel(models.Model):
COLORS = get_namedtuple_choices('COLORS', (
(0, 'black', 'Black'),
(1, 'white', 'White'),
))
colors = models.PositiveIntegerField(choices=COLORS)
>>> MyModel.COLORS.black
0
>>> MyModel.COLORS.get_choices()
[(0, 'Black'), (1, 'White')]
class OtherModel(models.Model):
GRADES = get_namedtuple_choices('GRADES', (
('FR', 'fr', 'Freshman'),
('SR', 'sr', 'Senior'),
))
grade = models.CharField(max_length=2, choices=GRADES)
>>> OtherModel.GRADES.fr
'FR'
>>> OtherModel.GRADES.get_choices()
[('fr', 'Freshman'), ('sr', 'Senior')]
Helpers
# get_choices()
>>> MyModel.COLORS.get_choices()
[(0, 'Black'), (1, 'White')]
# get_choices_dict()
>>> MyModel.COLORS.get_choices_dict()
OrderedDict([(1, 'Black'), (2, 'White')])
# get_all()
>>> lambda x: (print(color) for color in MyModel.COLORS.get_all())
(1, 'black', 'Black')
(2, 'white', 'White')
# get_choices_tuple()
>>> MyModel.COLORS.get_choices_tuple()
((1, 'black', 'Black'), (2, 'white', 'White'))
# get_values()
>>> MyModel.COLORS.get_values()
[1, 2]
# get_value_by_name()
>>> MyModel.COLORS.get_value_by_name('white')
2
# get_desc_by_value()
>>> MyModel.COLORS.get_desc_by_value(1)
Black
# get_name_by_value()
>>> MyModel.COLORS.get_name_by_value(1)
black
# is_valid()
>>> MyModel.COLORS.is_valid(1)
True
Get value from tuple by key
If you have a tuple my_tuple
and you want to get the value for the key my_key
, you can use the straight-forward
helper function get_value_from_tuple_by_key()
:
my_tuple = (
1, 'Value One',
2, 'Value Two',
)
my_value = get_value_from_tuple_by_key(my_tuple, 1)
# my_value = 'Value One'
Get key from tuple by value
If you have a tuple my_tuple
and you want to get the key for the value my_key
, you can use the straight-forward
helper function get_key_from_tuple_by_value()
:
my_tuple = (
1, 'Value One',
2, 'Value Two',
)
my_value = get_key_from_tuple_by_value(my_tuple, 'Value One')
# my_value = 1
String converter and utilities
Remove duplicates from list
Returns a list of unique entries from not_distinct_list
.
from ai_django_core.utils.string import distinct
not_distinct_list = ['Beer', 'Wine', 'Whiskey', 'Beer']
distinct_list = distinct(not_distinct_list)
# Result: ['Whiskey', 'Wine', 'Beer']
Note that the order might change due to internal casting to a set.
Slugify a filename
Turns a string into a nice slugified filename.
from ai_django_core.utils.string import slugify_file_name
filename = 'hola and hello.txt'
slug = slugify_file_name(filename)
# Result: "hola_and_hello.txt"
You can pass a parameter to control how many characters the slug is supposed to have.
from ai_django_core.utils.string import slugify_file_name
filename = 'a very long filename.txt'
slug = slugify_file_name(filename, 6)
# Result: "a_very.txt"
Smart truncate
This helper cuts a string at a word-boundary and therefore keeps words intact. Similar to djangos
default-filter truncatechars
, you can pass the desired string length.
from ai_django_core.utils.string import smart_truncate
my_sentence = 'I am a very interesting sentence.'
truncated_str = smart_truncate(my_sentence, 10)
# Result: "I am a..."
By default, after cutting the string, it will append “…” which can be configured as follows:
from ai_django_core.utils.string import smart_truncate
my_sentence = 'I am a very interesting sentence.'
truncated_str = smart_truncate(my_sentence, 10, '[...]')
# Result: "I am a[...]"
Converting a float to a German-formatted string
If you have a float which you like to convert to a properly formatted string (German format), then you can do this:
from ai_django_core.utils.string import float_to_string
float_str = float_to_string(1234.56)
# Result: "1234,56"
If you are not sure your float value will always be set, you can either use the default fallback or overwrite it with something custom.
from ai_django_core.utils.string import float_to_string
value = None
# Default fallback
fallback_result = float_to_string(value)
# Result: "0,00"
# Custom fallback
fallback_result = float_to_string(value, 'NaN')
# Result: "NaN"
Converting a date object to string
If you want to easily convert a date object to a string in the given format, just use this helper:
import datetime
from ai_django_core.utils.string import date_to_string
# Default format (German)
date_str = date_to_string(datetime.date(2020, 9, 19))
# Result: "19.09.1985"
# Custom format
date_str = date_to_string(datetime.date(2020, 9, 19), str_format='%Y-%m-%d')
# Result: "2020-09-19"
Again, you can set a replacement if the date object is None
:
import datetime
from ai_django_core.utils.string import date_to_string
# Default fallback
date_str = date_to_string(None)
# Result: "-"
# Custom fallback
date_str = date_to_string(None, 'no date')
# Result: "no date"
Converting a datetime object to string
If you want to easily convert a datetime object to a string in the given format, just use this helper:
import datetime
from ai_django_core.utils.string import datetime_to_string
# Default format (German)
datetime_str = datetime_to_string(datetime.datetime(2020, 9, 19, 8))
# Result: "19.09.1985"
# Custom format
datetime_str = datetime_to_string(datetime.datetime(2020, 9, 19, 8), str_format='%Y-%m-%d')
# Result: "2020-09-19"
Again, you can set a replacement if the datetime object is None
:
import datetime
from ai_django_core.utils.string import datetime_to_string
# Default fallback
datetime_str = datetime_to_string(None)
# Result: "-"
# Custom fallback
datetime_str = datetime_to_string(None, 'no datetime')
# Result: "no datetime"
Converting numbers to string
If you have a float or int variable which you like to convert to a properly formatted string, then you can do this:
from ai_django_core.utils.string import number_to_string
number_str = number_to_string(1234.56, decimal_digits=2)
# Result: "1,234.56"
If you are not sure your float value will always be set, you can either use the default fallback or overwrite it with something custom.
from ai_django_core.utils.string import number_to_string
value = None
# Default fallback
fallback_result = number_to_string(value)
# Result: "0,00"
# Custom fallback
fallback_result = number_to_string(value, replacement='NaN')
# Result: "NaN"
Furthermore, all values will be rounded to the number of decimal_digits
passed. Defaults to 0. Note, that the
result will NOT be localised!
Getting a value or a default
Similar to django filter default
, this method will return the value if it is not equal to None
and
will return the fallback value otherwise.
from ai_django_core.utils.string import string_or_none_to_string
value = 'I am a string.'
# Value set
result = string_or_none_to_string(value)
# Result: "I am a string."
# Value not set, default fallback value
result = string_or_none_to_string(None)
# Result: "-"
# Value not set, custom fallback value
result = string_or_none_to_string(None, replacement='empty')
# Result: "empty"
Lightweight XML to HTML converter
If you want a simple transformer from XML to HTML(-entities), you can use this helper:
from ai_django_core.utils.string import encode_to_xml
value = '<tag>Something with an ampersand (&)</tag>'
result = encode_to_xml(value)
# Result: "'<tag>Something with an ampersand (&)</tag>'"
This method will replace all “<”, “>” and “&” with their HTML representation.