2009-05-14 15 views
119

Ho modulo con un ingresso per la posta elettronica e due pulsanti di presentare per iscriversi e cancellarsi dalla newsletter:Come posso creare un modulo django con più pulsanti di invio?

<form action="" method="post"> 
{{ form_newsletter }} 
<input type="submit" name="newsletter_sub" value="Subscribe" /> 
<input type="submit" name="newsletter_unsub" value="Unsubscribe" /> 
</form> 

ho forma anche di classe:

class NewsletterForm(forms.ModelForm): 
    class Meta: 
     model = Newsletter 
     fields = ('email',) 

devo scrivere il mio metodo clean_email ed io è necessario sapere con quale pulsante è stato inviato il modulo. Ma il valore dei pulsanti di invio non è nel dizionario self.cleaned_data. Posso ottenere i valori dei pulsanti altrimenti?

risposta

70

È possibile utilizzare self.data nel metodo clean_email per accedere ai dati POST prima della convalida. Dovrebbe contenere una chiave denominata newsletter_sub o newsletter_unsub a seconda del pulsante premuto.

# in the context of a django.forms form 

def clean(self): 
    if 'newsletter_sub' in self.data: 
     # do subscribe 
    elif 'newsletter_unsub' in self.data: 
     # do unsubscribe 
+4

puoi dare un esempio annotato? sarebbe davvero d'aiuto – Jharwood

+7

Non penso che 'clean' non sia il posto giusto per fare la logica a livello di modello. È specifico per la pulizia di un modulo e la ricerca di qualsiasi 'ValidationError's che si estenda su più input. La risposta di Sven è più nella giusta direzione, ma non è ancora la risposta migliore – Patrick

+4

Rischio per la sicurezza! Usare i dati del modulo per apportare modifiche al database prima che il modulo sia stato convalidato è pericoloso. –

189

Esempio:

if 'newsletter_sub' in request.POST: 
    # do subscribe 
elif 'newsletter_unsub' in request.POST: 
    # do unsubscribe 
+0

La richiesta è disponibile nei metodi di convalida clean_xxx? – sureshvv

8

È anche possibile fare in questo modo,

<form method='POST'> 
    {{form1.as_p}} 
    <button type="submit" name="btnform1">Save Changes</button> 
    </form> 
    <form method='POST'> 
    {{form2.as_p}} 
    <button type="submit" name="btnform2">Save Changes</button> 
    </form> 

CODICE

if request.method=='POST' and 'btnform1' in request.POST: 
    do something... 
if request.method=='POST' and 'btnform2' in request.POST: 
    do something... 
+0

form1.as_p quando usarlo ?? nelle viste, durante il controllo della validità del modulo, vorrei poterlo fare ... form1.is_valid() quindi fare questo, form2.is_valid() fai questo .. – tilaprimera

3

È una vecchia domanda ora, tuttavia ho avuto lo stesso problema e ho trovato una soluzione che funziona per me: ho scritto MultiRedirectMixin.

from django.http import HttpResponseRedirect 

class MultiRedirectMixin(object): 
    """ 
    A mixin that supports submit-specific success redirection. 
    Either specify one success_url, or provide dict with names of 
    submit actions given in template as keys 
    Example: 
     In template: 
     <input type="submit" name="create_new" value="Create"/> 
     <input type="submit" name="delete" value="Delete"/> 
     View: 
     MyMultiSubmitView(MultiRedirectMixin, forms.FormView): 
      success_urls = {"create_new": reverse_lazy('create'), 
           "delete": reverse_lazy('delete')} 
    """ 
    success_urls = {} 

    def form_valid(self, form): 
     """ Form is valid: Pick the url and redirect. 
     """ 

     for name in self.success_urls: 
      if name in form.data: 
       self.success_url = self.success_urls[name] 
       break 

     return HttpResponseRedirect(self.get_success_url()) 

    def get_success_url(self): 
     """ 
     Returns the supplied success URL. 
     """ 
     if self.success_url: 
      # Forcing possible reverse_lazy evaluation 
      url = force_text(self.success_url) 
     else: 
      raise ImproperlyConfigured(
       _("No URL to redirect to. Provide a success_url.")) 
     return url 
+0

Dove e in che modo esattamente userete MultiRedirectMixin? Si prega di elaborare con un esempio. –

0

un url per la stessa vista! così!

###urls.py### 
url(r'^$', views.landing.as_view(), name = 'landing'), 

####views.py#### 
class landing(View): 
    template_name = '/home.html' 
    form_class1 = forms.pynamehere1 
    form_class2 = forms.pynamehere2 
     def get(self, request): 
      form1 = self.form_class1(None) 
      form2 = self.form_class2(None) 
      return render(request, self.template_name, { 'register':form1, 'login':form2,}) 

     def post(self, request): 
      if request.method=='POST' and 'htmlsubmitbutton1' in request.POST: 
        ## do what ever you want to do for first function #### 
      if request.method=='POST' and 'htmlsubmitbutton2' in request.POST: 
        ## do what ever you want to do for second function #### 
        ## return def post### 
      return render(request, self.template_name, {'form':form,}) 


####/home.html#### 
#### form 1 #### 
<form action="" method="POST" > 
    {% csrf_token %} 
    {{ register.as_p }} 
<button type="submit" name="htmlsubmitbutton1">Login</button> 
</form> 
#### form 2 #### 
<form action="" method="POST" > 
    {% csrf_token %} 
    {{ login.as_p }} 
<button type="submit" name="htmlsubmitbutton2">Login</button> 
</form> 
Problemi correlati