Models

This is a collection of django models base models that can be helpful in your implementations.

class awl.models.Choices

Note

Django 3.0 added Enumeration Types which solves the same problem as this class. You should probably use it instead.

A tuple of tuples pattern of ((id1, string1), (id2, string2)…) is common in django for choices fields, etc. This object inspects its own members (i.e. the inheritors) and produces the corresponding tuples.

class Colours(Choices):
    RED = 'r'
    LIGHT_BLUE = 'b'

>> Colours.RED
'r'
>> list(Colours)
[('r', 'Red'), ('b', 'Light Blue')]

A member value can also be a tuple to override the default string

class Colours(Choices):
    RED = 'r'
    BLUE = 'b', 'Blueish'

>> list(Colours)
[('r', 'Red'), ('b', 'Blueish')]

A inheriting class can also add or override members.

class Colours(Choices):
    RED = 'r'
    BLUE = 'b'

class MoreColours(Colours):
    GREEN = 'g'
    BLUE = 'b', 'Even More Blue'

>> list(Colours)
[('r', 'Red'), ('b', 'Even More Blue'), ('g', 'Green')]
class awl.models.Counter(*args, **kwargs)

A named counter in the database with atomic update.

exception DoesNotExist
exception MultipleObjectsReturned
classmethod increment(name)

Call this method to increment the named counter. This is atomic on the database.

Parameters:

name – Name for a previously created Counter object

class awl.models.Lock(*args, **kwargs)

Implements a simple global locking mechanism across database accessors by using the select_for_update() feature. Example:

# run once, or use a fixture
Lock.objects.create(name='everything')

# views.py
def something(request):
    Lock.lock_until_commit('everything')
exception DoesNotExist
exception MultipleObjectsReturned
classmethod lock_until_commit(name)

Grabs this lock and holds it (using select_for_update()) until the next commit is done.

Parameters:

name – Name for a previously created Lock object

class awl.models.QuerySetChain(*subquerysets)

Chains together multiple querysets (possibly of different models) and behaves as one queryset. Supports minimal methods needed for use with django.core.paginator. Does not support re-ordering or re-filtering across the set.

q1 = Thing.objects.filter(foo)
q2 = Stuff.objects.filter(bar)
qsc = QuerySetChain(q1, q2)
__init__(*subquerysets)
count()

Performs a .count() for all subquerysets and returns the number of records as an integer.