I have the following Model classes:
class ContactPerson(models.Model):
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class Appartment(models.Model):
contact_person = models.ForeignKey(ContactPerson)
Problem: In template file I want a user to fill contact person's name, so I overwrite contact_person field as follows:
class AppartmentSellForm(ModelForm):
contact_person = forms.CharField(max_length=30)
class Meta:
model = Appartment
In my view function I am doing the following to save data from a form submitted:
def appartment_submit(request):
if request.method == "POST":
form = AppartmentSellForm(request.POST)
if form.is_valid():
appartment = form.save(commit=False) # ERROR HERE
cp = models.ContactPerson(name=form.cleaned_data['contact_person'])
appartment.contact_person = cp
appartment.save()
form.save();
return HttpResponseRedirect('/sell/')
else:
form = AppartmentSellForm()
return render_to_response('sell_appartment_form.html', {'form' : form})
Error message:
#ValueError at /sell/sell_appartment/appartment_submit/
Cannot assign "u'blabla'": "Appartment.contact_person" must be a "ContactPerson" instance.**
I am using SQLite, and 开发者_JS百科django version 1.1.1
Question: How to solve this problem?
I think the code that you are putting in your view would be better suited to the ModelForm's validation.
Override the model form's clean_contact_person
method and add the code there so that it a) checks that the name is valid and if so, b) sets the form field's value to the actual ContactPerson instance.
Something like: (off the top of my head)
class AppartmentSellForm(ModelForm):
contact_person = forms.CharField(max_length=30)
class Meta:
model = Appartment
def clean_contact_person(self):
name = self.cleaned_data['contact_person']
# check the name if you need to
try:
# maybe check if it already exists?
person = models.ContactPerson.objects.get(name=name)
except ContactPerson.DoesNotExist:
person = models.ContactPerson(name=name)
# you probably only want to save this when the form is saved (in the view)
return person
Your view will may still need to use commit=False
(since you will need to save the ContactPerson record). You can do this using the save_m2m
method.
There's more info about save_m2m
in the ModelForm documentation and information about cleaning fields in the validation documentation.
I hope that helps, good luck!
You can do one of the following:
- Try to
exclude
thecontact_person
field, as mentioned in point 3 over here - or you could just not override the field in your
ModelForm
and Django will render it as aModelChoiceField
, unless you actually want people to type out a name instead of having a dropdown list to choose from.
精彩评论