I have a this model:
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, )
And then a form based on this model:
class FleetForm(ModelForm):
class Meta:
model = Fleet
exclude = ('company', )
When I use this form in a template, the "company" field is not added, which is expected. But that field is required as blank != True.
The way I use this form, the company attribute will always be known in the view function, as it's passed from the URL. How can I add the company to the form in the view function before I save it?
Here is my view:
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
There are two ways to solve this issue:
Instantiate your model with initial values for the missing, but required fields:
company = Company.objects.get(pk=company_id)
fleet = Fleet(company=company)
form = FleetForm(request.POST, instance=fleet)
new_fleet = form.save()
Use save(commit=False)
and manually set any extra required fields:
company = Company.objects.get(pk=company_id)
form = FleetForm(request.POST)
fleet = form.save(commit=False)
fleet.company = company
new_fleet = fleet.save()
See the note in this section of the ModelForm API documentation for more details.
By the way, either editable=False
or exclude
is enough to remove a field from a ModelForm
; you don't need both.
in @Ayman Hourieh 's answer . Just to address a pitfall in Django. If you have many-to-many field in the form. it would not get saved here. You should explicitly call save_m2m()
. add one more line as below.
form.save_m2m()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With