开发者

save data from form with custom foreign key field in django

开发者 https://www.devze.com 2023-03-31 01:29 出处:网络
I have the following Model classes: class ContactPerson(models.Model): name = models.CharField(max_length=30)

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:

  1. Try to exclude the contact_person field, as mentioned in point 3 over here
  2. or you could just not override the field in your ModelForm and Django will render it as a ModelChoiceField, unless you actually want people to type out a name instead of having a dropdown list to choose from.
0

精彩评论

暂无评论...
验证码 换一张
取 消