169 votes

Comment puis-je créer des boutons d'envoi multiples dans un formulaire Django ?

J'ai un formulaire avec une entrée pour l'email et deux boutons de soumission pour s'abonner et se désabonner de la newsletter :

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

J'ai aussi un formulaire de classe :

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

Je dois écrire ma propre méthode clean_email et j'ai besoin de savoir par quel bouton le formulaire a été soumis. Mais la valeur des boutons submit n'est pas dans le fichier self.cleaned_data dictionnaire. Pourrais-je obtenir les valeurs des boutons autrement ?

251voto

Oraculum Points 1409

Eg :

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

1 votes

La demande est-elle disponible dans les méthodes de validation clean_xxx ?

0 votes

Quelle méthode adopter ?

2 votes

@JonMcClung Inside def post(self, request, *args, **kwargs) .

109voto

Ayman Hourieh Points 39435

Vous pouvez utiliser self.data dans le clean_email pour accéder aux données POST avant la validation. Elle doit contenir une clé appelée newsletter_sub o newsletter_unsub en fonction de la touche sur laquelle on a appuyé.

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

Pouvez-vous donner un exemple annoté ? cela m'aiderait beaucoup.

11 votes

Je ne pense pas que clean n'est pas vraiment le bon endroit pour faire de la logique au niveau du modèle. C'est spécifiquement pour le nettoyage d'un formulaire et la recherche de toute ValidationError qui couvrent plusieurs entrées. La réponse de Sven va dans le bon sens, mais n'est pas nécessairement la meilleure.

9 votes

Risque de sécurité ! L'utilisation des données du formulaire pour effectuer des modifications dans la base de données avant que le formulaire n'ait été validé est dangereuse.

32voto

Nishant Points 135

Vous pouvez aussi faire comme ceci,

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

Form1.as_p quand l'utiliser ?? dans les vues, en vérifiant la validité du formulaire, j'aimerais pouvoir faire... form1.is_valid() puis faire ceci, form2.is_valid() faire cela...

7voto

chrisroker0 Points 1

Une url vers la même vue ! comme ça !

urls.py

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

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

5voto

Sven Points 304

C'est une vieille question maintenant, néanmoins j'ai eu le même problème et j'ai 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

1 votes

Où et comment allez-vous utiliser MultiRedirectMixin ? Veuillez élaborer avec un exemple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X