Làm thế nào tôi có thể xây dựng nhiều nút trình mẫu django?


155

Tôi có mẫu với một đầu vào cho email và hai nút gửi để đăng ký và hủy đăng ký nhận bản tin:

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

Tôi cũng có dạng lớp:

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

Tôi phải viết phương thức Clean_email của riêng mình và tôi cần biết nút nào đã được gửi. Nhưng giá trị của các nút gửi không có trong self.cleaned_datatừ điển. Tôi có thể nhận các giá trị của các nút khác không?

Câu trả lời:


96

Bạn có thể sử dụng self.datatrong clean_emailphương thức để truy cập dữ liệu POST trước khi xác thực. Nó nên chứa một khóa được gọi newsletter_subhoặc newsletter_unsubtùy thuộc vào nút nào được nhấn.

# 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
bạn có thể đưa ra một ví dụ chú thích? nó thực sự có ích
Jharwood

9
Tôi không nghĩ rằng đó cleankhông phải là nơi thích hợp để thực hiện logic cấp mô hình. Nó đặc biệt để làm sạch một biểu mẫu và tìm bất kỳ ValidationErrors nào trải rộng trên nhiều đầu vào. Câu trả lời của Sven đúng hơn, nhưng vẫn chưa hẳn là câu trả lời hay nhất
Patrick

8
Rủi ro bảo mật! Sử dụng dữ liệu biểu mẫu để thực hiện các thay đổi trong cơ sở dữ liệu trước khi biểu mẫu đã được xác thực là nguy hiểm.
Đô thị lượng tử

1
Bạn có thể muốn chạy các loại xác nhận khác nhau tùy thuộc vào nút nào được nhấn. Trong trường hợp đó, không có tác động "Bảo mật".
sureshvv

230

Ví dụ:

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

1
Yêu cầu có sẵn bên trong các phương thức xác thực Clean_xxx không?
sureshvv

Trong phương pháp này nên đi đâu?
Jon McClung

1
@JonMcClung Bên trong def post(self, request, *args, **kwargs).
A. Kali

23

Bạn cũng có thể làm như thế này,

 <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 khi nào nên sử dụng cái này ?? trong các khung nhìn, trong khi kiểm tra tính hợp lệ của biểu mẫu, tôi ước mình có thể làm ... form1.is_valid () sau đó làm điều này, form2.is_valid () làm điều này ..
tilaprimera

5

Bây giờ đây là một câu hỏi cũ, tuy nhiên tôi có cùng một vấn đề và tìm thấy một giải pháp hiệu quả cho tôi: Tôi đã viết 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

Chính xác thì bạn sẽ sử dụng MultiRedirectMixin ở đâu và như thế nào? Xin hãy giải thích với một ví dụ.
Saurav Kumar

4

một url để cùng xem! thích như vậy

url

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

lượt xem

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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.