18

Let's say I'm using the Django Site model:

class Site(models.Model):
    name = models.CharField(max_length=50)

My Site values are (key, value):

1. Stackoverflow
2. Serverfault
3. Superuser

I want to construct a form with an html select widget with the above values:

<select>
    <option value="1">Stackoverflow</option>
    <option value="2">Serverfault</option>
    <option value="3">Superuser</option>
</select>

I'm thinking of starting with the following code but it's incomplete:

class SiteForm(forms.Form):
    site = forms.IntegerField(widget=forms.Select())

Any ideas how I can achieve that with Django form?

EDIT

Different pages will present different site values. A dev page will show development sites while a cooking page will show recipe sites. I basically want to dynamically populate the widget choices based on the view. I believe I can achieve that at the moment by manually generating the html in the template.

Thierry Lam
  • 45,304
  • 42
  • 117
  • 144

2 Answers2

18

I think you're looking for ModelChoiceField.

UPDATE: Especially note the queryset argument. In the view that is backing the page, you can change the QuerySet you provide based on whatever criteria you care about.

Hank Gay
  • 70,339
  • 36
  • 160
  • 222
  • Can I specify the queryset in the view? – Thierry Lam Mar 31 '10 at 20:22
  • As in, provide the `QuerySet` to use whenever you instantiate your `Form`? I'm not sure. If your possibilities are limited, it seems fairly straightforward to provide a `Form` subclass tailored to the specific view you're using, e.g., `DeveloperSitesForm`, `EndUserSitesForm`, etc. – Hank Gay Mar 31 '10 at 20:33
  • 1
    I was able to do it from the code in that question: http://stackoverflow.com/questions/622982/django-passing-custom-form-parameters-to-formset – Thierry Lam Mar 31 '10 at 20:38
15

I haven't tested this, but I'm thinking something along the lines of...

site = forms.IntegerField(
    widget=forms.Select(
        choices=Site.objects.all().values_list('id', 'name')
        )
     )

Edit --

I just tried this out and it does generate the choices correctly. The choices argument is expecting a list of 2-tuples like this...

(
   (1, 'stackoverflow'),
   (2, 'superuser'),
   (value, name),
)

The .values_list will return that exact format provided you have the ID and the name/title/whatever as so: .values_list('id', 'name'). When the form is saved, the value of .site will be the id/pk of the selected site.

T. Stone
  • 19,209
  • 15
  • 69
  • 97
  • This will evaluate the Site queryset when the form is first defined. If the data changes, the form won't show the new data. – Daniel Roseman Mar 31 '10 at 21:43