2016-04-29 3 views
0

Я пытаюсь найти лучший способ иметь поле с несколькими типами контента. Что я сделал до сих пор является Контактная модель с 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 

Тогда, на мой взгляд, я бы выбрал правильную форму в зависимости от запроса аргумента (например:/контакты/добавить/электронная почта/или контакт/добавить/телефон).

Я пытаюсь найти самый элегантный способ сделать это, поэтому любая помощь приветствуется.

Спасибо за чтение.

ответ

0

Если вы хотите использовать один html-файл, то это одно из решений.

class YourView(TemplateView): 
    template_name = 'your_template.html' 

    def get(self, request, *args, **kwargs): 
     context = self.get_context_data(**kwargs) 
     if context['type'] == 'phone': 
      context['form'] = ContactPhoneForm 
     elif ... 

если вы установите вид, то

<form action="{% url "your view" %}" enctype="multipart/form-data" method="POST">{% csrf_token %} 
{% if form.contenttype == 'phone' %} 
    {% include "partials/contact_phone_form.html" with form=form %} 
{% elif form.contenttype == 'email' %} 
    {% include "partials/contact_email_form.html" with form=form %} 
{% else %} 
    do something. 
{% endif %} 
</form> 

и contact_phone_form.html и contact_email_form это выглядит

anything. 
<input name='phone'> 
anything. 

это решение для одного шаблона, мульти формы.

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

class YourView(TemplateView): 
    template_name = 'your_template.html' 

    def get(self, request, *args, **kwargs): 
     context = self.get_context_data(**kwargs) 
     if context['type'] == 'phone': 
      template_name = 'phone_form_template.html' 
     elif context['type'] == 'email': 
      template_name = 'email_form_template.html' 
     ... 
0

Я хотел бы использовать forms.Form в зависимости от запроса аргумент, как:?

/контакты/добавить/тип = адрес электронной почты или/контакты/добавить/тип = телефон

и поэтому вы можете использовать его как (не проверенный код):

class ContactForm(forms.Form): 

    def __init__(self, *args, **kwargs): 
     super(CreateUserquestionnaireForm, self).__init__(*args, **kwargs) 
     if "email" in self.data: 
      ... do some thing like change contact type or widget 
     if "phone" in self.data: 
      ... do some thing like change contact type or widget 
Смежные вопросы