2009-06-06 6 views
5

J'ai ce modèle:Substituer une valeur de champ absent lors de l'enregistrement d'un ModelForm

class Fleet(models.Model): 
    company  = models.ForeignKey("Company", editable=False) 
    aircraft = models.ForeignKey("Aircraft") 
    size  = models.IntegerField(default=1) 
    description = models.TextField(blank=True) 

    def __unicode__(self): 
     return u"%s" % (self.aircraft,) 

Et puis un formulaire basé sur ce modèle:

class FleetForm(ModelForm): 
    class Meta: 
     model = Fleet 
     exclude = ('company',) 

Quand j'utiliser ce formulaire dans un modèle, le champ "company" n'est pas ajouté, ce qui est attendu. Mais ce champ est requis comme vide! = Vrai.

La manière dont j'utilise ce formulaire, l'attribut company sera toujours connu dans la fonction view, car il est transmis depuis l'URL. Comment puis-je ajouter la société au formulaire dans la fonction de vue avant de l'enregistrer?

Voici mon avis:

def new_fleet(request, company_id): 
    from forms import FleetForm 

    company = Company.objects.get(pk=company_id) 

    if request.method == "POST": 
     form = FleetForm(request.POST,) 

     form.company = company   #doesn't work 

     form = form.save(commit=False) #can't do this because the form 
     form.company = company   #doesn't validate (company is not set) 

     if not form.errors: 
      form.save() 

    else: 
     fleet = Fleet(company=company) #pointless because the company widget 
     form = FleetForm(instance=fleet) #isn't created but eh whatever 

Répondre

8

Il y a deux façons de résoudre ce problème:

instancier votre modèle avec des valeurs initiales pour les disparus, mais les champs requis:

company = Company.objects.get(pk=company_id) 
fleet = Fleet(company=company) 
form = FleetForm(request.POST, instance=fleet) 
new_fleet = form.save() 

Utilisez save(commit=False) et définissez manuellement tous les champs obligatoires supplémentaires:

company = Company.objects.get(pk=company_id) 
form = FleetForm(request.POST) 
fleet = form.save(commit=False) 
fleet.company = company 
new_fleet = fleet.save() 

Voir la note dans this section of the ModelForm API documentation pour plus de détails. Par ailleurs, soit editable=False soit exclude est suffisant pour supprimer un champ d'un ModelForm; tu n'as pas besoin des deux.

1

dans la réponse de @Ayman Hourieh. Juste pour répondre à un piège à Django. Si vous avez un champ plusieurs-à-plusieurs dans le formulaire. il ne serait pas sauvé ici. Vous devez appeler explicitement save_m2m(). ajouter une ligne supplémentaire comme ci-dessous.

form.save_m2m() 
Questions connexes