5

Мой forms.py:Как использовать две разные формы Django в одном шаблоне?

class AlertForm(forms.ModelForm): 
class Meta: 
    model=Alert 
    fields = ('high','medium', 'user') 
    widgets = { 
     'user': forms.HiddenInput() 
    } 

AlertCountFormset = modelformset_factory(Alert, 
             form = AlertForm) 

Другая форма Django класс:

class NotifierForm(forms.ModelForm): 
high = forms.ChoiceField(choices=NOTIFIER_TYPE) 
medium = forms.ChoiceField(choices=NOTIFIER_TYPE) 
low = forms.ChoiceField(choices=NOTIFIER_TYPE) 

def save(self, commit=True): 
    alert = super(NotifierForm, self).save(commit=False) 
    alert.high = self.cleaned_data["high"] 
    alert.medium = self.cleaned_data["medium"] 
    alert.low = self.cleaned_data["low"] 
    alert.save() 
    return alert 

class Meta: 
    model=Notifier 
    fields = ('high','medium', 'low', 'user') 
    widgets = { 
     'user': forms.HiddenInput() 
    } 

NotifierFormset = modelformset_factory(Notifier, 
            form = NotifierForm) 

Ниже для выбора полей:

NOTIFIER_TYPE = (
(0, _('E-mail')), 
(1, _('Skype')), 
(2, _('IRC')) 
) 

Я хочу, чтобы заполнить эти две формы в то же шаблон. Поэтому я выбираю писать одни и те же представления для обоих, т.е.:

def profile_setting(request, slug): 
if request.method == 'POST': 
    alert_form = AlertForm(request.POST) 
    notifier_form = NotifierForm(request.POST) 
    if alert_form.is_valid() and notifier_form.is_valid(): 
     alert = alert_form.save(commit=False) 
     notifier = notifier_form.save(commit=False) 
     alert.user = request.user.username 
     notifier.user = request.user.username 
     notifier.save() 
     alert.save() 
     return HttpResponseRedirect(reverse('profile_setting', args=[slug])) 

extra_context = { 
    'alert_form': AlertForm(), 
    'notifier_form': NotifierForm() 
} 
return direct_to_template(request,'users/user_profile_setting.html', 
          extra_context) 

В соответствии с этим в моем template.html:

{% block content %} 
<h3>{% trans "Alerts limit" %}</h3> 
<form action="" method="POST">{% csrf_token %} 
    {{ alert_form.as_p }} 
    <input type="submit" value="{% trans 'Update' %}" /> 
</form> 

<h3>{% trans "Notifier setting" %}</h3> 
<form action="" method="POST">{% csrf_token %} 
    {{ notifier_form.as_p }} 
    <input type="submit" value="{% trans 'Update' %}" /> 
</form> 

Все правильно, он сохраняет данные в базу данных также. Но проблема возникает всякий раз, когда я заполняю aler_form и нажимаю кнопку обновления. он также обновляет другую форму с тем же значением или наоборот. Например, если я выбираю

1 2 3 for high , medium and low for alert_Form 

Затем оно также сохраняет то же значение для notify_form. Почему это происходит. Это что-то не так с представлениями?

ответ

12

Используйте аргумент prefix, чтобы ваши имена полей не столкнулись.

Например:

alert form = AlertForm(request.POST, prefix='alert') 
notifier_form = NotifierForm(request.POST, prefix='notifier') 

Вы должны использовать один и тот же префикс в ваших несвязанных форм.

extra_context = { 'alert_form': AlertForm(prefix='alert'), notifier_form': NotifierForm(prefix='notifier') } 

Преимущество использования префикса в том, что вам не нужно вручную переименовать поля, так как umnik700 предлагает в своем ответе.

+0

Помимо этого меняется. Должен ли я вносить изменения в сторону шаблона или нет? –

+0

Нет, вам не нужно вносить какие-либо изменения в шаблон. – Alasdair

+0

После добавления. Ничего не происходит. Я имею в виду, что никакая ценность не вводится в базу данных. Даже ошибки нет –

3

Проблема в том, что на ваших формах поля имеют одинаковые имена.

request.POST - словарь-подобный объект. Поэтому он содержит только пары имя/значение из запроса. Если имена полей одинаковы на обоих формах тогда, когда вы звоните

alert_form = AlertForm(request.POST) 
notifier_form = NotifierForm(request.POST) 

они инициализируются с теми же значениями. Чтобы устранить это, сделайте имена уникальными между двумя вашими формами. Например, префикс всех имен полей в AlertForm с «alert_».

+0

Извините, я не получил вас. Какие два имени? –

+0

Спасибо за ответ :) Еще одна вещь. Возможно ли это в Django-Form, когда я собираюсь обновить все поля в формах. Все поля должны показывать предыдущее сохраненное значение в базе данных. –

+1

Да, это возможно. Экстра_контекст, содержащий два экземпляра формы. Как вы это делаете прямо сейчас, вы проходите неинициализированные формы. Если вы хотите отобразить данные, необходимые для их инициализации. –

Смежные вопросы