сохранить данные из формы с настраиваемым полем внешнего ключа в Django - PullRequest
3 голосов
/ 28 августа 2011

У меня есть следующие классы моделей:

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)

Проблема: В файле шаблона я хочу, чтобы пользователь заполнил имя контактного лица, поэтому я перезаписываю поле contact_person следующим образом:

class AppartmentSellForm(ModelForm):
    contact_person = forms.CharField(max_length=30)

    class Meta:
        model = Appartment

В функции просмотра я делаю следующее, чтобы сохранить данные из отправленной формы:

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})

Сообщение об ошибке :

#ValueError at /sell/sell_appartment/appartment_submit/

Cannot assign "u'blabla'": "Appartment.contact_person" must be a "ContactPerson" instance.**

Я использую SQLite, и django версии 1.1.1

Вопрос: Как решить эту проблему?

Ответы [ 2 ]

1 голос
/ 28 августа 2011

Я думаю, что код, который вы помещаете в ваше представление, лучше подходит для проверки ModelForm.

Переопределите метод clean_contact_person формы модели и добавьте туда код, чтобы он a) проверял правильность имени и, если да, b) устанавливал значение поля формы в фактический экземпляр ContactPerson.

Что-то вроде: (от макушки)

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

Возможно, вашему представлению все равно придется использовать commit=False (поскольку вам необходимо сохранить запись ContactPerson). Вы можете сделать это, используя метод save_m2m.

Более подробная информация о save_m2m в документации ModelForm и информация об очистке полей в документации проверки .

Надеюсь, это поможет, удачи!

0 голосов
/ 28 августа 2011

Вы можете сделать одно из следующих действий:

  1. Попробуйте exclude поле contact_person, как указано в пункте 3 здесь
  2. или вы можете просто не переопределить поле в ModelForm, и Django отобразит его как ModelChoiceField, если вы на самом деле не хотите, чтобы люди вводили имя, вместо того, чтобы иметь выпадающий список для выбора.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...