2009-05-14 13 views
119

Je forme avec une entrée pour le courrier électronique et deux boutons de soumission pour vous abonner et vous désabonner de la newsletter:Comment puis-je créer plusieurs formulaires de soumission de formulaire django?

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

Je forme aussi classe:

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

je dois écrire ma propre méthode de clean_email et je besoin de savoir par quel bouton a été envoyé le formulaire. Mais la valeur des boutons de soumission ne figure pas dans le dictionnaire self.cleaned_data. Pourrais-je obtenir des valeurs de boutons sinon?

Répondre

70

Vous pouvez utiliser self.data dans la méthode clean_email pour accéder aux données POST avant la validation. Il doit contenir une clé appelée newsletter_sub ou newsletter_unsub selon le bouton enfoncé.

# 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

pouvez-vous donner un exemple annoté? cela aiderait vraiment – Jharwood

+7

Je ne pense pas que «nettoyer» n'est pas vraiment le bon endroit pour faire de la logique au niveau du modèle. C'est spécifiquement pour nettoyer un formulaire et trouver n'importe quel 'ValidationError's qui couvrent plusieurs entrées. La réponse de Sven est plus dans la bonne direction, mais toujours pas nécessairement la meilleure réponse – Patrick

+4

Risque de sécurité! L'utilisation de données de formulaire pour apporter des modifications à la base de données avant la validation du formulaire est dangereuse. –

189

Par exemple:

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

Une requête est-elle disponible dans les méthodes de validation clean_xxx? – sureshvv

8

Vous pouvez aussi faire comme ça,

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

CODE

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 quand l'utiliser? dans les vues, tout en vérifiant la validité du formulaire, je voudrais pouvoir faire ... form1.is_valid() alors faites-le, form2.is_valid() faites ceci .. – tilaprimera

3

C'est une vieille question maintenant, néanmoins j'ai eu le même problème et trouvé une solution qui fonctionne pour moi: j'ai écrit 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

Où et comment exactement utiliserez-vous MultiRedirectMixin? S'il vous plaît élaborer avec un exemple. –

0

une url à la même vue! comme ça!

###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> 
Questions connexes