Я пытаюсь найти лучший способ иметь поле с несколькими типами контента. Что я сделал до сих пор является Контактная модель с contacttype CharField:Django: одна модель, разные формы и виджеты?
class Contact(models.Model):
CONTACT_TYPES = (
('email', 'Email'),
('phone', 'Phone'),
('address', 'Address'),
('facebook', 'Facebook'),
('linkedin', 'LinkedIn'),
('youtube', 'Youtube'),
('twitter', 'Twitter'),
('google', 'Google'),
)
teammember = models.ForeignKey(TeamMember)
description = models.CharField(max_length=100, null=True)
contacttype = models.CharField(max_length=100, choices= CONTACT_TYPES, default='email')
contact = models.TextField()
Моя цель состоит в том, чтобы позволить пользователю добавлять различные информацию контакта, which'll быть перечислены на странице профиля, но только один модель.
Я думал о классе для каждого ModelForm:
class ContactForm(ModelForm):
def __init__(self, data, *args, **kwargs):
super(ModelForm, self).__init__(data, *args, **kwargs)
self.contacttype = ""
class Meta:
model = Contact
fields = ['description', 'contact']
widgets = {'contact': TextInput()}
def clean_contacttype(self):
return self.contacttype
class ContactEmailForm(ContactForm):
def __init__(self, data, *args, **kwargs):
super(ContactForm, self).__init__(data, *args, **kwargs)
self.contacttype = "email"
class Meta(ContactForm.Meta):
model = Contact
fields = ['description', 'contact']
widgets = {'contact': EmailInput()}
class ContactPhoneForm(ContactForm):
def __init__(self, data, *args, **kwargs):
super(ContactForm, self).__init__(data, *args, **kwargs)
self.contacttype = "phone"
class Meta(ContactForm.Meta):
model = Contact
fields = ['description', 'contact']
widgets = {'contact': TextInput()}
def clean_contact(self):
cleaned_data = super(ContactForm, self).clean()
contact = cleaned_data.get("contact")
# Perform some phone number validations
return contact
Тогда, на мой взгляд, я бы выбрал правильную форму в зависимости от запроса аргумента (например:/контакты/добавить/электронная почта/или контакт/добавить/телефон).
Я пытаюсь найти самый элегантный способ сделать это, поэтому любая помощь приветствуется.
Спасибо за чтение.