Загрузка и сохранение данных из отношений m2m в виджетах Textarea с помощью ModelForm

У меня есть модель, которая выглядит примерно так:

class Business(models.Model):
    name = models.CharField('business name', max_length=100)
    # ... some other fields
    emails = models.ManyToManyField(Email, null=True)
    phone_numbers = models.ManyToManyField(PhoneNumber, null=True)
    urls = models.ManyToManyField(URL, null=True)

и соответствующая ModelForm:

class BusinessContactForm(forms.ModelForm):
    emails = forms.CharField(widget=forms.Textarea(attrs={'rows':4,'cols':32}))
    phone_numbers = forms.CharField(widget=forms.Textarea(attrs={'rows':4,'cols':32}))
    urls = forms.CharField(widget=forms.Textarea(attrs={'rows':4,'cols':32}))

    class Meta:
        model = Business
        fields = ['emails', 'phone_numbers', 'urls',]

Мой вопрос: как лучше всего загрузить существующие электронные письма, номера телефонов и URL-адреса в виджеты Textarea при представлении формы (по одному на строку в соответствующих виджетах)?

Затем, после того, как форма была изменена и отправлена, как лучше всего добавить новые адреса электронной почты, номера или URL-адреса (отношения m2m) и удалить те, которых больше нет в списке (также убедившись, что не добавлены дубликаты)?


person John Debs    schedule 10.08.2009    source источник


Ответы (2)


Это действительно не очень хороший способ сделать это. наборы форм предназначены для работы со связанными элементами в формах. .

Вместо того, чтобы определять связанные поля как дополнительные поля в модели BusinessForm, используйте стандартную форму для контакта с адресом электронной почты, телефоном и URL-адресом. Затем передайте это в modelformset_factory, чтобы создать встроенный набор форм для вашей формы BusinessContact.

person Daniel Roseman    schedule 10.08.2009
comment
Я думал об использовании наборов форм, но казалось, что это будет более простой пользовательский интерфейс и более чистый код в целом (при условии, что я смогу заставить его работать так, как я себе это представлял, что бывает редко). Тем не менее, я пробовал наборы форм, но мне не понравилось, что мне пришлось создавать по одному для каждого из трех элементов в представлении (электронная почта, телефон, URL-адрес), а затем также проверять и обрабатывать данные из каждого. Вы упомянули встроенный формат для формы BusinessContact — это особый тип набора форм? Если да, то не могли бы вы немного уточнить? Спасибо! - person John Debs; 11.08.2009
comment
Я также должен отметить: я не создавал один набор форм со всеми тремя элементами, потому что пользователь должен иметь возможность указать разные номера каждого из них (возможно, один или два URL-адреса, несколько номеров телефонов и несколько адресов электронной почты). - person John Debs; 11.08.2009
comment
Итак, я исследовал встроенные наборы форм после того, как вы упомянули о них (я несколько раз просматривал документацию и сумел пропустить эту часть), и они, кажется, позаботятся обо всех сложностях, которые мне нужны... Мне придется жить с созданием одного набора форм для каждое связанное поле и перемещение их в отношения «многие к одному». Спасибо за помощь. - person John Debs; 11.08.2009

Это не прямой ответ на ваш вопрос. Это скорее предложение переосмыслить вашу модель данных.

Похоже, что ваша BusinessContactForm представляет виджеты textarea для вставки нескольких строк в базу данных. Я бы не стал использовать виджет Textarea для нескольких элементов более ограниченного типа: я бы вводил номера телефонов с виджетом номера телефона, URL-адреса с виджетом URL и электронные письма с виджетом электронной почты.

Деловой контакт — это человек, который работает в компании и имеет адрес электронной почты и номер телефона, верно? Так почему бы не смоделировать бизнес-контакт таким образом и не иметь внешнего ключа к бизнесу?

Это скорее подход, который я бы выбрал.

person hughdbrown    schedule 10.08.2009
comment
Причина, по которой я сделал это таким образом, заключается в том, что контактная информация может указывать не только на одного человека — например, адрес электронной почты [email protected] или номер телефона 1-800-Busines принадлежат как самой компании, так и не конкретное лицо (а вдруг их подменили?). Я имел в виду передать каждую строку в поле соответствующего типа для проверки, но проблема сохранения этой ссылки на объект БД (как это делает ModelForm с базовой моделью) при попытке сохранить элементы после проверки остается . - person John Debs; 11.08.2009
comment
Поэтому я переместил каждое поле в отдельные таблицы с отношениями «многие к одному». Подробности смотрите в моем комментарии к ответу ниже. - person John Debs; 11.08.2009