views:

250

answers:

2

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:

views.py

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.

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

Can this be done?

+1  A: 

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.

celopes
+2  A: 

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

views.py

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
Matt McCormick