Choices vs optgroups in Django widgets

optgroups are used in most widgets that are used by the ChoiceField or fields that inherit from it. If customization of the field classes or their template is required, understanding optgroups is very important.

An optgroup is a way of grouping related choices together and displaying them in the widget. This allows users to easily identify related options. For example, you could use optgroups to group countries by region. optgroups can be nested to create a hierarchy of options.


Choices

Normally we configure the choices of a field by setting a tuple of value and label pairs.


 class SomeModel(models.Model):
     # ... other fields
     country = models.CharField(
         max_length=255,
         choices=(('HR', 'Croatia'), ('GB', 'Great Britain'), ('MX', 'Mexico')),
     )
            
Choices example #1

However, grouping these options is possible, too.


 class SomeModel(models.Model):
     # ... other fields
     country = models.CharField(
         max_length=255,
         choices=(
             ('Europe', (('HR', 'Croatia'), ('GB', 'Great Britain')),
             ('North America', (('MX', 'Mexico'))
         ),
     )
            
Choices example #2

Optgroup representation of choices

Unlike the choices tuple, optgroups tuple always has the same data structure. The tuple is consisted of triplets: group, options, index.

The optgroups in the example above would look like this:


 optgroups = [
      # Group name, options, index
      (None, (('AG', 'Algeria'), 0),
      (None, (('IT', 'Italy')), 1),
	  (None, (('HR', 'Croatia')), 2),
	  (None, (('MX', 'Mexico')), 3),
 ]
            
Optgroup example #1

The optgroups for the second example are a bit more complex, but they conform to the same format:


 optgroups = [
     ('Africa', [('AG', 'Algeria')], 0),
     ('Europe', [('IT', 'Italy'), ('HR', 'Croatia')], 1),
     ('North America', [('MX', 'Mexico')], 2),
 ]
            
Optgroup example #2