5

Mi forms.py:¿Cómo usar dos Formularios Django diferentes en la misma plantilla?

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

AlertCountFormset = modelformset_factory(Alert, 
             form = AlertForm) 

otra clase de formulario de 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) 

a continuación es para los campos de opciones:

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

Quiero llenar estas dos formas al mismo modelo. Así que decide escribir mismos puntos de vista, tanto para decir:

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) 

acuerdo con que en mi 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> 

Todo es correcto, es guardar los datos en la base de datos también. Pero el problema es siempre que llené el aler_form y hago clic en el botón de actualización. también actualiza el otro formulario con el mismo valor o viceversa. Por ejemplo, si elijo

1 2 3 for high , medium and low for alert_Form 

Luego, también guarda el mismo valor para notify_form. Por qué está pasando esto. ¿Hay algo mal con las vistas?

Respuesta

12

Utilice el argumento prefix para que los nombres de sus campos no entren en conflicto.

Por ejemplo:

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

Es necesario utilizar el mismo prefijo en sus formas no unidas.

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

La ventaja de usar el prefijo es que no es necesario cambiar manualmente el nombre de los campos, como umnik700 sugiere en su respuesta.

+0

Aparte de esos cambios. ¿Debo hacer cambios al lado de la plantilla o no? –

+0

No, no es necesario que realice ningún cambio en la plantilla. – Alasdair

+0

Después de agregarlo. Nada esta pasando. Quiero decir, ningún valor ingresa a la base de datos. Incluso no hay error –

3

El problema es que en sus formularios los campos tienen los mismos nombres.

request.POST es un objeto tipo diccionario. Por lo tanto, solo contiene los pares nombre/valor de la solicitud. Si los nombres de campo son los mismos en ambos formularios, cuando llame a

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

se inicializan con los mismos valores. Para resolver esto, haga que los nombres sean únicos entre sus dos formularios. Por ejemplo, prefija todos los nombres de campo en AlertForm con "alert_".

+0

Lo siento, no te tengo. ¿Qué dos nombres? –

+0

Gracias por la respuesta :) Una cosa más. ¿Es esto posible en Django-Form, cada vez que voy a actualizar todos mis campos en los formularios? Todos los campos deben mostrar el valor guardado previamente en la base de datos. –

+1

Sí, es posible. El contexto_extra que contiene dos instancias de formulario. La forma en que lo haces ahora es que pasas formularios no inicializados. Si desea visualizar los datos, necesita inicializarlos. –

Cuestiones relacionadas