Opened 19 years ago
Closed 18 years ago
#4091 closed (worksforme)
Not able to get choices widget to auto selected="selected" on model_for_instance
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Forms | Version: | 0.96 | 
| Severity: | Keywords: | foreignkey selected choices | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | no | 
| Easy pickings: | no | UI/UX: | no | 
Description
It may have to do how I have my models defined (such as the str() function), but if I use form_for_instance
on an instance with a model that has foreign keys, it will not put selected="selected" on the appropriate choices.
Here are my models:
class Students(models.Model):
    ssn = models.CharField(unique=True, maxlength=11)
    name = models.CharField(blank=True, maxlength=50)
    address = models.CharField(blank=True, maxlength=50)
    dob = models.DateField(null=True, blank=True)
    email = models.CharField(blank=True, maxlength=50)
    level = models.CharField(blank=True, maxlength=5)
    
    def __str__(self):
      return self.ssn
class Courses(models.Model):
    cid = models.CharField(unique=True, maxlength=7)
    level = models.CharField(blank=True, maxlength=5)
    description = models.TextField(blank=True, maxlength=100)
    
    def __str__(self):
      return self.cid
class Semesters(models.Model):
    sname = models.CharField(unique=True, maxlength=20)
    
    def __str__(self):
      return self.sname
class Takes(models.Model):
    student = models.ForeignKey(Students, to_field='ssn', db_index=True, db_column='ssn')
    course = models.ForeignKey(Courses, to_field='cid', db_index=True, db_column='cid')
    semester = models.ForeignKey(Semesters, to_field='sname', db_index=True, db_column='sname')
    grade = models.CharField(blank=True, maxlength=2)
    
    def __str__(self):
      return "%s - %s" % (self.course.cid, self.semester.sname)
Now I want to do a form_for_instance on a Takes instance and I expect the appropriate student, course, and semester to have selected="selected"
in the html.
So now I do this:
instance = Takes.objects.get(id=1) formClass = forms.form_for_instance(instance) form = formClass(auto_id='form_%s') print form
And I get no selected="selected". Now I've studied the documentation thoroughly, and they said this happens
when they are not "bound". However, I thought form_for_instance makes it bound? Am I doing something wrong or is this a bug?
To circumvent this problem, I've resorted to the following:
formClass = forms.form_for_instance(instance)
for field in formClass.base_fields:
  if hasattr(formClass.base_fields[field], 'choices'):
    for option_value, option_label in formClass.base_fields[field].choices:
      if formClass.base_fields[field].initial == option_label:
        formdict.update({field: option_value})
        break
  else:
    formdict.update({field: formClass.base_fields[field].initial})
The above code does exactly what I want, it puts the selected="selected" on the right choices.
Change History (1)
comment:1 by , 18 years ago
| Resolution: | → worksforme | 
|---|---|
| Status: | new → closed | 
| Triage Stage: | Unreviewed → Accepted | 
I used the following model:
from django.db import models from django import newforms as forms # Create your models here. class ZoneGeographique(models.Model): nom = models.CharField(maxlength=256) def __str__(self): return self.nom class Admin: pass class Ville(models.Model): pays = models.ForeignKey(ZoneGeographique) nom = models.CharField(maxlength=256) def __str__(self): return self.nom + " en " + self.pays.nom class Admin: passThen from the django shell:
The right instance is selected. It works