2009-07-18 40 views
7

Các mô hình suggested để xử lý một hình thức trong một cái nhìn dường như quá phức tạp và không DRY với tôi:Phương án thay thế cho bản mẫu soạn thảo django?

def contact(request): 
    if request.method == 'POST': # If the form has been submitted... 
     form = ContactForm(request.POST) # A form bound to the POST data 
     if form.is_valid(): # All validation rules pass 
      # Process the data in form.cleaned_data 
      # ... 
      return HttpResponseRedirect('/thanks/') # Redirect after POST 
    else: 
     form = ContactForm() # An unbound form 

    return render_to_response('contact.html', { 
     'form': form, 
    }) 

Đó là rất nhiều điều kiện, nó lặp lại() xây dựng ContactForm, và toàn bộ khối được lặp đi lặp lại ở khắp mọi nơi một khung nhìn cần xử lý một biểu mẫu. Có cách nào tốt hơn không?

+0

Django có chế độ xem chung từ nhiều năm. Câu hỏi này và tất cả các câu trả lời tôi thấy là lỗi thời. Xem: https://docs.djangoproject.com/en/1.9/ref/class-based-views/generic-editing/ – guettli

Trả lời

10

Bạn có thể tránh sự lặp lại, tất nhiên. Chủ yếu, bạn cần chuyển vào làm đối số lớp của biểu mẫu và tên mẫu để sử dụng, có thể gọi để xử lý dữ liệu đã được làm sạch khi biểu mẫu hợp lệ được gửi và đích đến cho chuyển hướng sau khi xử lý như vậy; Ngoài ra, bạn cần thêm một chút mã để gọi lớp biểu mẫu chỉ một lần, để tạo ra một dạng ràng buộc hoặc không ràng buộc và xử lý nó đúng cách. Ví dụ:

def process_any_form(request, 
        form_class, template_file_name, 
        process_data_callable, redirect_destination): 

    form = form_class(request.POST if request.method == 'POST' else None) 

    if form.is_bound and form.is_valid(): 
     process_data_callable(form.cleaned_data) 
     return HttpResponseRedirect(redirect_destination) 

    return render_to_response(template_file_name, {'form': form}) 
+2

Tác phẩm này hoạt động. Nếu mẫu không chỉ là 'biểu mẫu', bạn sẽ cần phải mở rộng danh sách đối số để bao gồm, ví dụ: giá trị băm. –

+0

s/băm/dict /, nhưng, vâng, ý tưởng hay: bạn có thể vượt qua trong một dict bán trước d điền cho bối cảnh, và sử dụng dict (d, form = form) làm bối cảnh cho hiển thị, điều này làm cho giải pháp thậm chí còn tổng quát hơn. –

2

Cách soạn thảo mẫu soạn sẵn kết hợp hai mối quan tâm: trình bày biểu mẫu để chỉnh sửa và xử lý kết quả. Bạn có thể chia thành hai phương thức, điều này sẽ giới thiệu một số bản sao dưới dạng các lệnh gọi render_to_response() giống hệt nhau. Vào thời điểm bạn đã cấu trúc lại điều đó, bạn có thể kết thúc bằng nội dung nào đó ít có thể đọc hơn so với biểu mẫu một phương thức ở trên.

Khi tôi xem xét phương pháp soạn sẵn, tôi không thấy sao chép. Hai cách sử dụng ContactForm() khác nhau rõ rệt. Hai điều kiện dường như cho tôi khá sạch sẽ cho thấy các quá trình chuyển đổi trạng thái liên quan đến việc xử lý một biểu mẫu (trình bày một mẫu trống, chấp nhận các đệ trình cho đến khi một bản hợp lệ, xử lý và chuyển hướng).

0

Người ta có thể viết một hàm xử lý các điều kiện cho tất cả các biểu mẫu. Bạn có thể làm điều này bằng cách đi qua trong một chức năng cụ thể để hình thức mà sau khi "is_valid", chẳng hạn như:

def FormHandler(request, CleaningFunction, redirecturl): 
    if request.method = 'POST': 
     if request.method == 'POST': # If the form has been submitted... 
      form = ContactForm(request.POST) # A form bound to the POST data 
      if form.is_valid(): # All validation rules pass 
       CleaningFunction(form) # Process the data in form.cleaned_data 
       return HttpResponseRedirect('/thanks/') # Redirect after POST 
    else: 
     form = ContactForm() # An unbound form 
    return form 

Sau đó, bạn sẽ gọi FormHandler khỏi tầm nhìn của bạn. Lưu ý rằng điều này không được kiểm tra và có thể có lỗi.

1

xử lý chung của Alex đánh bại tôi vào nó, nhưng FWIW chúng ta có xu hướng hướng tới một phiên bản kém chung của đề nghị của ông:

def contact(request): 
    post_data = request.POST if request.method == 'POST' else None 
    form = ContactForm(post_data) 
    if request.method == 'POST': 
     # perform normal validation checking, etc 

    return render_to_response('contact.html', { 
     'form': form, 
     }) 

Nếu post_data là Không, sau đó các mẫu được khởi tạo như là không bị chặn. Nếu không, xử lý bị ràng buộc vẫn tiếp tục như bình thường. Nó tránh được việc xây dựng liên hệ trùng lặp của ContactForm, nhưng tôi đồng ý với câu trả lời của Dave rằng việc xây dựng bản sao không làm phiền tôi như là một bản sao chính xác bởi vì các tham số xây dựng là khác nhau.

1

Tôi đã quá mệt mỏi về điều này mà tôi đã viết quan điểm chung của riêng tôi để xử lý nó. Trong quá trình này, tôi phát hiện ra rằng django already has underdocumented generic views để xử lý biểu mẫu. Chúng tương đối trực tiếp với các chế độ xem chung được ghi lại, nhưng chấp nhận các biểu mẫu và về cơ bản tuân theo cùng một mẫu mà bạn đã sử dụng trong ví dụ của mình. Cuối cùng, tôi thấy chúng quá không linh hoạt và ngu xuẩn cho việc sử dụng của tôi (tôi không muốn có chế độ xem create_or_update, tôi không muốn xử lý hai hành động đó một cách riêng biệt.)

Edit: Bạn không thích câu trả lời của Fragsworth. với cùng một điều tôi đang nói về, tôi cho rằng bạn sẽ không giống như tôi. Đây là một ví dụ về cách nó hoạt động.

# in urls.py 
urlpatterns += patterns("", 
    (u'^...$', 'django.views.generic.create_update.update', { 
     'form_class': ContactForm }) 
) 

ContactForm phải có phương thức save() và đó là nơi xử lý biểu mẫu của bạn.

0

Bạn có thể bỏ qua mô-đun biểu mẫu của django và chỉ làm theo cách thời trang cũ, bạn sẽ linh hoạt hơn mà không mất quá nhiều IMHO.

Thời gian qua tôi đã xem biểu mẫu django khá lâu trước đây, tôi không biết mọi thứ đã thay đổi chưa, nhưng ví dụ, nó không thực sự cho phép bạn xây dựng biểu mẫu kiểu ajax; ít nhất là không dễ dàng.

6

Bạn đang đúng nó có thể được tốt hơn, đây là một lựa chọn tốt hơn (nhưng tiếp tục đọc):

def contact(request): 
    form = ContactForm(request.POST or None) # A form bound to the POST data 
    if form.is_valid(): # All validation rules pass 
     # Process the data in form.cleaned_data 
     # ... 
     return HttpResponseRedirect('/thanks/') # Redirect after POST 

    return render_to_response('contact.html', { 
     'form': form, 
    }) 

đoạn này xuất phát từ một cuộc nói chuyện gọi Advanced Django Form Usage từ DjangoCon11.

Lưu ý rằng điều này sẽ xử lý biểu mẫu trống là hợp lệ (thậm chí trước khi gửi) nếu tất cả các trường là tùy chọn và bạn không sử dụng bảo vệ CSRF. Vì vậy, để loại bỏ rủi ro đó, bạn nên sử dụng điều này tốt hơn:

def contact(request): 
    form = ContactForm(request.POST or None) # A form bound to the POST data 
    if request.method == 'POST' and form.is_valid(): # All validation rules pass 
     # Process the data in form.cleaned_data 
     # ... 
     return HttpResponseRedirect('/thanks/') # Redirect after POST 

    return render_to_response('contact.html', { 
     'form': form, 
    }) 
Các vấn đề liên quan