2009-05-14 27 views
119

tengo forma de una entrada para el correo electrónico y dos botones de envío para suscribirse y darse de baja del boletín de noticias:¿Cómo puedo construir múltiples botones de envío formulario django?

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

tengo formulario también clase:

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

tengo que escribir mi propio método clean_email y yo Necesito saber por qué botón se envió el formulario. Pero el valor de los botones de enviar no está en el diccionario self.cleaned_data. ¿Podría obtener valores de botones de lo contrario?

Respuesta

70

Puede usar self.data en el método clean_email para acceder a los datos POST antes de la validación. Debe contener una clave llamada newsletter_sub o newsletter_unsub según el botón que se haya presionado.

# 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

¿Puedes dar un ejemplo anotado? realmente ayudaría – Jharwood

+7

No creo que 'clean' no sea realmente el tipo correcto de lugar para hacer la lógica a nivel de modelo. Específicamente para limpiar un formulario y encontrar cualquier 'ValidationError's que abarque múltiples entradas. La respuesta de Sven va más en la dirección correcta, pero aún no es necesariamente la mejor respuesta – Patrick

+4

¡Riesgo de seguridad! El uso de datos de formulario para realizar cambios en la base de datos antes de que se haya validado el formulario es peligroso. –

189

Ej:

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

¿La solicitud está disponible dentro de los métodos de validación clean_xxx? – sureshvv

8

También puede hacerlo de esta manera,

<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> 

CÓDIGO

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 cuándo usar esto ?? en las vistas, mientras verificaba la validez del formulario, me gustaría poder ... form1.is_valid() hacer esto, form2.is_valid() hacer esto .. – tilaprimera

3

Ahora es una vieja pregunta, sin embargo, tuve el mismo problema y encontré una solución que me funciona: escribí 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

¿Dónde y cómo usará MultiRedirectMixin exactamente? Por favor, elabore con un ejemplo. –

0

one url to the same view! como tal!

###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> 
Cuestiones relacionadas