Best practice for Python & Django constants


Question

I have a Django model that relies on a tuple. I'm wondering what the best practice is for refering to constants within that tuple for my Django program. Here, for example, I'd like to specify "default=0" as something that is more readable and does not require commenting. Any suggestions?

Status = (
    (-1, 'Cancelled'),
    (0, 'Requires attention'),
    (1, 'Work in progress'),
    (2, 'Complete'),
)

class Task(models.Model):
    status = models.IntegerField(choices=Status, default=0) # Status is 'Requires attention' (0) by default.

EDIT:

If possible I'd like to avoid using a number altogether. Somehow using the string 'Requires attention' instead would be more readable.

1
37
10/10/2012 3:28:34 PM

Accepted Answer

It is quite common to define constants for the integer values as follows:

class Task(models.Model):
    CANCELLED = -1
    REQUIRES_ATTENTION = 0
    WORK_IN_PROGRESS = 1
    COMPLETE = 2

    Status = (
        (CANCELLED, 'Cancelled'),
        (REQUIRES_ATTENTION, 'Requires attention'),
        (WORK_IN_PROGRESS, 'Work in progress'),
        (COMPLETE, 'Complete'),
    )

    status = models.IntegerField(choices=Status, default=REQUIRES_ATTENTION)

By moving the constants and Status inside the class, you keep the module's namespace cleaner, and as a bonus you can refer to Tasks.COMPLETE wherever you import the Tasks model.

58
10/10/2012 3:42:04 PM

CANCELED, ATTENTION, WIP, COMPLETE = range(-1, 3)
Status = (
    (CANCELED, 'Cancelled'),
    (ATTENTION, 'Requires attention'),
    (WIP, 'Work in progress'),
    (COMPLETE, 'Complete'),
)

class Task(models.Model):
    status = models.IntegerField(choices=Status, default=CANCELED)


Keep in mind that as others noted, the proper way is to put these variables inside your Model class. That's also how the official django example does it.

There is only one reason where you'd want to put it outside the class namespace and that is only if these semantics are equally shared by other models of your app. i.e. you can't decide in which specific model they belong.

Though it doesn't seem like this is the case in your particular example.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon