title: How to group the choices in a Django Select widget?
body: <p>Is it possible to created <em>named choice groups</em> in a Django select (dropdown) widget, when that widget is on a form that is <em>auto-generated</em> from a data Model? Can I create the widget on the left-side picture below?  </p>
  
  <p><img src="https://i.stack.imgur.com/o54cq.png" alt="Two widgets with one grouped"></p>
  
  <p>My first experiment in creating a form with named groups, was done <em>manually</em>, like this:</p>
  
  <pre><code>class GroupMenuOrderForm(forms.Form):
      food_list = [(1, 'burger'), (2, 'pizza'), (3, 'taco'),]
          drink_list = [(4, 'coke'), (5, 'pepsi'), (6, 'root beer'),]
          item_list = ( ('food', tuple(food_list)), ('drinks', tuple(drink_list)),)
          itemsField = forms.ChoiceField(choices = tuple(item_list))
  
      def GroupMenuOrder(request):
          theForm = GroupMenuOrderForm()
          return render_to_response(menu_template, {'form': theForm,})
          # generates the widget in left-side picture
  </code></pre>
  
  <p>And it worked nicely, creating the dropdown widget on the left, with named groups.</p>
  
  <p>I then created a data Model that had basically the same structure, and used Django's ability to auto-generate forms from Models. It worked - in the sense that it showed all of the options. But the options were not in named groups, and so far, I haven't figured out how to do so - if it's even possible.</p>
  
  <p>I have found several questions, where the answer was, “create a form constructor and do any special processing there”. But It seems like the forms.ChoiceField requires a <em>tuple</em> for named groups, and I’m not sure how to convert a tuple to a QuerySet (which is probably impossible anyway, if I understand QuerySets correctly as being pointer to the data, not the actual data).</p>
  
  <p>The code I used for the data Model is:</p>
  
  <pre><code>class ItemDesc(models.Model):
      ''' one of "food", "drink", where ID of “food” = 1, “drink” = 2 '''
      desc = models.CharField(max_length=10, unique=True)
      def __unicode__(self):
          return self.desc
  
  class MenuItem(models.Model):
      ''' one of ("burger", 1), ("pizza", 1), ("taco", 1),
          ("coke", 2), ("pepsi", 2), ("root beer", 2) '''
      name = models.CharField(max_length=50, unique=True)
      itemDesc = models.ForeignKey(ItemDesc)
      def __unicode__(self):
          return self.name
  
  class PatronOrder(models.Model):
      itemWanted = models.ForeignKey(MenuItem)
  
  class ListMenuOrderForm(forms.ModelForm):
      class Meta:
          model = PatronOrder
  
  def ListMenuOrder(request):
      theForm = ListMenuOrderForm()
      return render_to_response(menu_template, {'form': theForm,})
      # generates the widget in right-side picture
  </code></pre>
  
  <p>I'll change the data model, if need be, but this seemed like a straightforward structure. Maybe too many ForeignKeys? Collapse the data and accept denormalization? :) Or is there some way to convert a tuple to a QuerySet, or <em>something</em> acceptable to a ModelChoiceField?</p>
  
  <p><strong>Update:</strong> final code, based on <a href="https://stackoverflow.com/users/341480/meshantz">meshantz</a>' <a href="https://stackoverflow.com/questions/5080828/how-to-group-the-choices-in-a-django-select-widget/5081418#5081418">answer</a>:</p>
  
  <pre><code>class FooIterator(forms.models.ModelChoiceIterator):
      def __init__(self, *args, **kwargs):
          super(forms.models.ModelChoiceIterator, self).__init__(*args, **kwargs)
      def __iter__(self):
              yield ('food', [(1L, u'burger'), (2L, u'pizza')])
              yield ('drinks', [(3L, u'coke'), (4L, u'pepsi')])
  
  class ListMenuOrderForm(forms.ModelForm):
      def __init__(self, *args, **kwargs):
          super(ListMenuOrderForm, self).__init__(*args, **kwargs)
          self.fields['itemWanted'].choices = FooIterator()
      class Meta:
          model = PatronOrder
  </code></pre>
  
  <p>(Of course the actual code, I'll have something pull the item data from the <em>database</em>.)</p>
  
  <p>The biggest change from the djangosnippet he linked, appears to be that Django has incorporated some of the code, making it possible to directly assign an Iterator to <em>choices</em>, rather than having to override the entire class. Which is very nice.</p>