Take the 2-minute tour ×

Is it possible to set a form's ForeignKey field's queryset so that it will take separate queryset's and output them in <optgroup>'s?

Here is what I have:


form = TemplateFormBasic(initial={'template': digest.template.id})
form.fields['template'].queryset = Template.objects.filter(Q(default=1) | Q(user=request.user)).order_by('name')

In my Template model, I have default Templates and User-created templates. I want them to be visibly separated in the <select> box eg.

  <optgroup label="Default Templates">
    <option>Default 1</option>
    <option>Default 2</option>
  <optgroup label="User Templates">
    <option>User Template 1</option>
    <option>User Template 2</option>

Can this be done?

share|improve this question
add comment

2 Answers

up vote 8 down vote accepted

I was able to figure it out using the example given on this blog


form.fields['template'].choices = templates_as_choices(request)

def templates_as_choices(request):
    templates = []
    default = []
    user = []
    for template in Template.objects.filter(default=1).order_by('name'):
        default.append([template.id, template.name])

    for template in Template.objects.filter(user=request.user).order_by('name'):
        user.append([template.id, template.name])

    templates.append(['Default Templates', default])
    templates.append(['User Templates', user])

    return templates
share|improve this answer
add comment

I've done in the past by not using a foreign key on the form, but rather a charfield with choices.

A CharField with choices support optgroups. You need to have the choices in this format:

('Group 1',(('1','Yada'),('2','Yada'))), ('Group 2',(('3','Bepety'),('4','Bopity')))

Choices can also be a callable. So I created my own function that traverses the models and builds a tuple like the above.

share|improve this answer
Thanks .. This was what i was looking for.. –  Ryu_hayabusa Dec 22 '13 at 16:41
add comment

Your Answer


