top of page

How to configure permanent system-wide variables for a Django app

Imagine a web application built with Django that requires a property that can be set by some user, and is then visible to all users. For example, let's say you're building a pay management system that provides some users with admin credentials, who can configure system-wide settings like pay period and holiday pay. How could something like this be implemented without unnecessary code duplication?


One option is to use environment variables, which are always visible to the application, but these have the drawback of not being easily modified from within the application. Another option is to store this information in the "User" or "Pay" table within the database, but this has the drawback of requiring the information to be duplicated for every entry to the table.


A new model

A great solution to this common problem lies within the database (which is always visible to the application), but not within any of the existing tables. We can create a new table specifically for this use-case that requires only one entry for each system variable. To accomplish this, we'll add a new model to our Django app. We can call it "SystemVariable", and it would look like this:


class SystemVariable(models.Model):
    name = models.CharField(primary_key=True, max_length=200)
    value = models.CharField(max_length=200)

    def __str__(self):
        return "Name: %s, value: %s" % (self.name, self.value)

Setting and getting

Setting and getting values from this table is straightforward. For either one, we first check if an entry exists for the variable we're looking for. When getting a value, we'd return the value of the entry if it exists and return some default value or null if not. When setting a value, we update the existing entry if it exists and add a new entry if not. The code to achieve this for a pay period length system variable is written here:


def get_pay_period_length_days():
    if not SystemVariable.objects.filter(name='PAY_LEN').exists():
        return null
    return int(SystemVariable.objects.get(name='PAY_LEN').value)

def set_pay_period_length_days(int_value):
    if SystemVariable.objects.filter(name='PAY_LEN').exists():
        SystemVariable.objects.filter(name='PAY_LEN')
        .update(value=str(int_value))
    else:
        SystemVariable(name='PAY_LEN', value=str(int_value)).save()

Obviously, this is only one approach to solving this problem. The main requirements for any solution are that wherever the data is stored is visible to all users of the platform, and the data storage solution is easily configurable from within the application.


Thanks for reading!

Comments


bottom of page