5

mio forms.py:Come utilizzare due diversi Django Form nello stesso modello?

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

AlertCountFormset = modelformset_factory(Alert, 
             form = AlertForm) 

Un'altra Django classe Form:

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) 

sotto è per i campi di scelta:

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

voglio riempire queste due forme allo stesso modello. Così ho scelto di scrivere stessi punti di vista, sia per vale a dire:

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) 

Secondo che nel mio 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> 

Tutto è giusto, è il salvataggio dei dati nel database anche. Ma il problema è quando ho riempito il aler_form e clicco sul buttone di aggiornamento. aggiorna anche l'altro modulo con lo stesso valore o viceversa. Per esempio se scelgo

1 2 3 for high , medium and low for alert_Form 

Quindi salva anche lo stesso valore per notify_form. Perché sta succedendo. È qualcosa che non va nelle opinioni?

risposta

12

Utilizzare l'argomento prefix in modo che i nomi dei campi non entrino in conflitto.

Ad esempio:

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

è necessario utilizzare lo stesso prefisso nei moduli non legati.

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

Il vantaggio di utilizzare il prefisso è che non è necessario rinominare manualmente i campi, come suggerisce umnik700 nella loro risposta.

+0

A parte queste modifiche. dovrei apportare modifiche al lato modello o no? –

+0

No, non è necessario apportare modifiche al modello. – Alasdair

+0

Dopo averlo aggiunto. Non sta succedendo niente Voglio dire, nessun valore sta entrando nel database. Anche se non vi è alcun errore –

3

Il problema è che nei moduli i campi hanno lo stesso nome.

request.POST è un oggetto simile al dizionario. Quindi contiene solo le coppie nome/valore dalla richiesta. Se i nomi dei campi sono uguali su entrambi i moduli, quando si chiama

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

vengono inizializzati con gli stessi valori. Per risolvere questo, i nomi devono essere unici tra le due forme. Ad esempio, prefisso tutti i nomi dei campi su AlertForm con "alert_".

+0

Scusa se non ti ho preso. Quali due nomi? –

+0

Grazie per la risposta :) Un'altra cosa. È possibile in Django-Form, ogni volta che aggiornerò tutti i miei campi nei moduli. Tutti i campi dovrebbero mostrare il valore salvato precedente nel database. –

+1

Sì, è possibile. Il extra_context che contiene due istanze del modulo. Il modo in cui lo fai adesso è che passi le forme non inizializzate. Se si desidera visualizzare i dati è necessario inizializzarli. –

Problemi correlati