Skip to main content
Join the official 2019 Python Developers SurveyStart the survey!

Convenient constants fields for Django

Project description

Django Konst

CircleCI Codecov Code style: black

django-konst

django-konst is a utility for Django that makes the definition, use and storage of both integer and string based constants easy and readable. It avoids passing of constants into template contexts and makes evaluation concise and readable.

It also makes exposure of these constants via forms and DRF serializers simple.

Definition

Constants can be defined with friendly names, backed by either integers or text.

Constants

from konst import Constant

# states backed by integers
states = Constants(
    Constant(pending=0),
    Constant(active=1),
    Constant(inactive=2)
)

# and another set of constants backed by strings
colours = Constants(
    Constant(red="FF0000"),
    Constant(green="00FF00"),
    Constant(yellow="FFFF80"),
    Constant(white="FFFFFF")
)

Constant groups

At times, it will be necessary to group constants and test membership within that group. To achieve this, django-konst provides a ConstantGroup class.

from konst import Constant, ConstantGroup

# states backed by integers
states = Constants(
    Constant(active=0),
    Constant(cancelled_ontime=1),
    Constant(cancelled_late=2),
    ConstantGroup(
        "cancelled",
        ("cancelled_ontime", "cancelled_late")
    )
)

Within a model

While not strictly necessary, it is advisable to effectively namespace your constants by defining them in the scope of a model definition. This means you have your constants wherever you have the model class, as well as any model instance.

from django.db import models
from django.utils.translation import ugettext_lazy as _

from konst import Constant, ConstantGroup, Constants
from konst.models.fields import (
    ConstantChoiceCharField,
    ConstantChoiceField
)

class Apple(models.Model):

    purposes = Constants(
        Constant(cooking=0, label=_("Cook me!")),
        Constant(eating=1, label=_("Eat me!")),
        Constant(juicing=2, label=_("Juice me!")),
        Constant(ornamental=3, label=_("Just look how pretty I am!")),
        ConstantGroup(
            "culinary", ("cooking", "eating", "juicing")
        )
    )
    colours = Constants(
        Constant(red="FF0000", label=_("red")),
        Constant(green="00FF00", label=_("green")),
        Constant(yellow="FFFF80", label=_("yellow")),
        Constant(white="FFFFFF", label=_("white")),
    )

    name = models.CharField(max_length=30)
    purpose = ConstantChoiceField(constants=purposes)
    colour = ConstantChoiceCharField(constants=colours, max_length=30)

Use

The entire point of this library is to make the use of constants defined in this way easy and concise.

In code

apple = Apple.objects.get(name='Granny Smith')
apple.purpose.cooking
True
apple.colour.red
True
apple.colour.green
False

# we don't care about the specific purpose, just whether it is as food
# or not, so use the ConstantGroup!
apple.purpose.culinary
True

In templates

{% if apple.purpose.eating %}
    You should bite this {{ apple.name }}!
{% endif %}

With Django's ORM

red_apples = Apple.objects.filter(colour=Apple.colours.red)
culinary_apples = Apple.objects.filter(
    purpose__in=Apple.purposes.culinary
)

With Django Rest Framework

Using the konst.extras.drf.fields.ConstantChoiceField serializer field with the Django Rest Framework it is possible to both output and receive constant values.

from konst.extras.drf.fields import ConstantChoiceField

from rest_framework import serializers


class AppleSerializer(serializers.ModelSerializer):

    purpose = ConstantChoiceField(Apple.purposes)
    colour = ConstantChoiceField(Apple.colours)

    class Meta:
        model = Apple
        fields = (
            "name", "purpose", "colour"
        )


# let's see how it handles bad values
serializer = AppleSerializer(
    data={
        "name": "Fuji",
        "colour": "blue",
        "purpose": "dicing"
    }
)
serializer.is_valid()
False
serializer.errors
{
    'colour': [u'"blue" is not a valid choice.'],
    'purpose': [u'"dicing" is not a valid choice.']
}


# and now how it handles some good values
serializer = AppleSerializer(
    data={
        "name": "Fuji",
        "colour": "red",
        "purpose": "eating"
    }
)
serializer.is_valid()
True


# let's create a database entry!
instance = serializer.save()


# and now our instance can be interacted with neatly
instance.colour.red
True


# finally, let's see how this looks when rendering JSON
AppleSerializer(instance=instance).data
{
    "name": "Fuji",
    "colour": "red",
    "purpose": "eating"
}

Contribute

django-konst supports a variety of Python and Django versions. It's best if you test each one of these before committing. Our Circle CI Integration will test these when you push but knowing before you commit prevents from having to do a lot of extra commits to get the build to pass.

Environment Setup

In order to easily test on all these Pythons and run the exact same thing that CI will execute you'll want to setup pyenv and install the Python versions outlined in tox.ini.

If you are on Mac OS X, it's recommended you use brew. After installing brew run:

$ brew install pyenv pyenv-virtualenv pyenv-virtualenvwrapper

Then:

pyenv install -s 2.7.14
pyenv install -s 3.4.7
pyenv install -s 3.5.4
pyenv install -s 3.6.3
pyenv virtualenv 2.7.14
pyenv virtualenv 3.4.7
pyenv virtualenv 3.5.4
pyenv virtualenv 3.6.3
pyenv global 2.7.14 3.4.7 3.5.4 3.6.3
pip install detox

To run test suite:

Make sure you are NOT inside a virtualenv and then:

$ detox

This will execute the testing matrix in parallel as defined in the tox.ini.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for django-konst, version 1.0.2
Filename, size File type Python version Upload date Hashes
Filename, size django_konst-1.0.2-py3-none-any.whl (12.7 kB) File type Wheel Python version py3 Upload date Hashes View hashes
Filename, size django-konst-1.0.2.tar.gz (9.8 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page