Django - Choices for Models

DavidL picture DavidL · Apr 25, 2011 · Viewed 13.2k times · Source

I have been searching and looking through docs, but I want to ask and confirm for the best solution here.

Trying to define model choices.

  1. 'yes, no and not sure' choice From Radio Select
  2. How would I define for Multiple Choices

Simple Example: In my models.py, I have

class Property(models.Model):
    name = models.CharField()

class Feature(models.Model):
    YES_CHOICES = (       # example of 1, there can be only one selection
        ('YES', 'Yes'),
        ('NO', 'No'),
        ('NOT_SURE', 'Not Sure')
    )
    PARKING_CHOICES = (    # example of 2, there can be multiple selections
        ('GARAGE', 'Garage'),
        ('STREET', 'Street'),
        ('PRIVATE_LOT', 'Private Lot'),
        ('VALET', 'Valet'),
    )

    nearby_school = models.CharField(max_length=8, choices=YES_CHOICES)
    parking_options = models. MultipleChoiceField(choices=PARKING_CHOICES)

class PropertyFeature(models.Model)
    property = models.ForeignKey(Property)
    feature = models.ForeignKey(Feature)
    ...

Are those best ways to do it?

  1. Should I use NullBooleanField instead for yes, no , not sure question?
  2. Is that a correct way for defining and storing for multiple choice answers? Sometimes, I see people using manytomany objects.

Just want to use the most efficient and the easiest method offered from Django.

Answer

supervacuo picture supervacuo · Aug 31, 2012

18 months or so later, there is now a better way of dealing with choices in Django; Łukasz Langa's dj.choices. An example of its use, from the blog post introducing the project:

from dj.choices import Choices, Choice

class Gender(Choices):
    male = Choice("male")
    female = Choice("female")
    not_specified = Choice("not specified")

class User(models.Model):
    gender = models.IntegerField(choices=Gender(),
            default=Gender.not_specified.id)

    def greet(self):
        gender = Gender.from_id(self.gender)
        if gender == Gender.male:
            return 'Hi, boy.'
        elif gender == Gender.female:
            return 'Hello, girl.'
        else:
            return 'Hey there, user!'

This still won't work for multiple selections, though.