title: Grouping ManyToMany values in template/formset
body: <p>I have a content-analysis application in which comments are tagged.  Each of the tags has a "connotation."  Because the multiple tags can apply to multiple comments, I've set up a many-to-many relationship between the Tags models and the Comments model.  The Tags model has a field for the connotation.  I have a working formset with the exception of this usability feature.</p>
  
  <h2>From models.py</h2>
  
  <pre><code>class Tags( models.Model ):
  
      CONNOTATION_CHOICES = ( ( '+', 'Positive' ), ( '-', 'Negative' ), ( '?', 'Ambivalent' ), ( '=', 'Informational' ), )
  
      tag = models.CharField( max_length = 40, blank = False )
      description = models.TextField( blank = True )
      connotation = models.CharField( max_length = 1, choices = CONNOTATION_CHOICES, blank = False )
  
      def __str__( self ):
          return "".join(( self.connotation, self.tag ))
  
  
  class Comments( models.Model ):
  
      comment     = models.TextField( blank = False )
      tags        = models.ManyToManyField( Tags )
      coder       = models.ForeignKey( User, null = True, blank = True )
      coder_comment = models.TextField( blank = True )
  
      def __str__( self ):
          return "{0} [{1}]".format( self.comment[:40], self.coder ) 
  </code></pre>
  
  <h2>From forms.py</h2>
  
  <pre><code>class CommentForm( forms.ModelForm ):
      class Meta:
          model = Comments
          fields = [ 
                  'tags',
                  'comment',
                  'coder',
                  'coder_comment',
                  ]
          widgets = {
                  'tags': forms.CheckboxSelectMultiple(),
                  }
  </code></pre>
  
  <h2>From views.py</h2>
  
  <pre><code>def edit( request ):
      FormSet = modelformset_factory( Comments, form=CommentForm, extra=0 )
  
      # Form not submitted, need to generate a blank one
      if request.method != 'POST':
          query = Comments.objects.all()
  
          group_by = 25
          paginator = Paginator( query, group_by )
  
          try:
              page = request.GET.get( 'page' )
              comments = paginator.page( page )
          except ( PageNotAnInteger, KeyError ):
              comments = paginator.page( 1 )
          except EmptyPage:
              comments = paginator.page( paginator.num_pages )
  
          page_query = query.filter( id__in = [ comment.id for comment in comments ] )
          formset = FormSet( queryset = page_query )
  
          context = { 'comments': comments, 'formset': formset }
          return render( request, 'commoncore/edit.html', context )
  
      # Submitted, so validate and process data
      else:
          # . . .
  </code></pre>
  
  <p>My question:  In the template, I'd like to group the tags by connotation.  Something like</p>
  
  <pre><code>{% for form in formset %}
      &lt;td&gt;
      {% for t in form.tags %}
          {% if t.connotation == "+" %}{{ t.tag }}{% endif %}
      {% endfor %}
      &lt;/td&gt;
      &lt;td&gt;
      {% for t in form.tags %}
          {% if t.connotation == "-" %}{{ t.tag }}{% endif %}
      {% endfor %}
      &lt;/td&gt;
      &lt;td&gt;
      {% for t in form.tags %}
          {% if t.connotation == "?" %}{{ t.tag }}{% endif %}
      {% endfor %}
      &lt;/td&gt;
      &lt;td&gt;
      {% for t in form.tags %}
          {% if t.connotation == "=" %}{{ t.tag }}{% endif %}
      {% endfor %}
      &lt;/td&gt;
  {% endfor %}
  </code></pre>
  
  <p>But this does not work because <code>t</code> apparently does not actually have access to <code>Tag</code>'s fields --- or at least I cannot discover where they are hidden.  Is it necessary to provide multiple tag lists filtered in <code>views.py</code>?  Or, I could write a template filter based on the <code>__str__()</code> representation of the Tags, but that seems a bit clunky.  Is there a better way?</p>