여러 개의 제출 버튼 장고 양식을 어떻게 만들 수 있습니까?


156

뉴스 레터를 구독하고 구독을 취소 할 수있는 이메일 입력 하나와 제출 버튼 두 개가있는 양식이 있습니다.

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

나는 또한 수업 양식을 가지고 있습니다 :

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

내 clean_email 메소드를 작성해야하며 양식이 제출 된 단추를 알아야합니다. 그러나 제출 버튼의 값은 self.cleaned_data사전에 없습니다 . 그렇지 않으면 버튼 값을 얻을 수 있습니까?

답변:


97

당신은 사용할 수 있습니다 self.data에서 clean_email검증하기 전에 POST 데이터에 액세스하는 방법. 그것은이라는 키가 포함되어야 newsletter_sub하거나 newsletter_unsub눌러 진 버튼에 따라.

# 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
주석이 달린 예를 들어 줄 수 있습니까? 정말 도움이 될 것입니다
Jharwood

9
clean모델 수준의 논리를 수행하는 데 적합한 장소 가 아니라고 생각 합니다. 양식을 정리하고 ValidationError여러 입력에 걸쳐 있는 모든 것을 찾는 데 사용 됩니다. Sven의 답변은 올바른 방향에 있지만 더 좋은 답변은 아닙니다.
Patrick

8
보안 위험! 양식이 검증되기 전에 양식 데이터를 사용하여 데이터베이스를 변경하는 것은 위험합니다.
Quant Metropolis

1
어떤 버튼을 눌렀는지에 따라 다른 유형의 유효성 검사를 실행할 수 있습니다. 이 경우 "보안"영향이 없습니다.
sureshvv

230

예 :

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

1
clean_xxx 검증 방법 내에서 요청을 사용할 수 있습니까?
sureshvv

이것은 어떤 방법으로 가야합니까?
Jon McClung

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

23

당신은 또한 이렇게 할 수 있습니다

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

암호

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

이것을 사용할 때 form1.as_p ?? 양식의 유효성을 확인하면서보기에, 나는이 .. 할) (내가 할 수있는 ... form2.is_valid, 다음이 작업을 수행) (form1.is_valid 바랍니다
tilaprimera

5

그럼에도 불구하고 지금은 오래된 질문이지만 동일한 문제가 발생하여 나에게 맞는 해결책을 찾았습니다 .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

MultiRedirectMixin을 어디에서 어떻게 정확하게 사용 하시겠습니까? 예를 들어 설명하십시오.
Saurav Kumar

4

하나의 URL을 동일한 뷰로! 그렇게!

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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.