2010-03-09 34 views
30

Các biểu mẫu này đang trưng bày chính xác đối diện hành vi mà tôi muốn.Các biểu mẫu của Django: yêu cầu trước tiên?

Quan điểm của tôi được thiết lập như thế này:

def post(request): # TODO: handle vehicle formset 
    VehicleFormSetFactory = formset_factory(VehicleForm, extra=1) 
    if request.POST: 
     vehicles_formset = VehicleFormSetFactory(request.POST) 
    else: 
     vehicles_formset = VehicleFormSetFactory() 

Và mẫu của tôi trông như thế này:

<div id="vehicle_forms"> 
     {{ vehicles_formset.management_form }} 
     {% for form in vehicles_formset.forms %} 
      <h4>Vehicle {{forloop.counter}}</h4> 
      <table> 
       {% include "form.html" %} 
      </table> 
     {% endfor %} 
    </div> 

Bằng cách đó nó ban đầu chỉ tạo ra 1 hình thức, như tôi muốn. Nhưng tôi muốn có một hình thức được yêu cầu!

Khi tôi tự động thêm biểu mẫu trống bằng JavaScript và vehicles_formset.empty_form tất cả các biểu mẫu bổ sung đó là bắt buộc, mà tôi không muốn.

Từ các tài liệu:

Các formset là đủ thông minh để bỏ qua các hình thức bổ sung mà không được thay đổi.

Đây là hành vi biểu mẫu đầu tiên được trưng bày (không phải những gì tôi muốn) nhưng không phải là hành vi mà các biểu mẫu bổ sung đang trưng bày (những gì tôi muốn).

Có một số thuộc tính tôi có thể thay đổi thành ít nhất là thực hiện một mẫu đơn không?

+0

@ mpen mặc dù tôi đến trễ cho bữa tiệc, tôi đã tự hỏi làm thế nào để đi về một vấn đề hơi khác nhau mà tôi đang đối mặt với câu hỏi của tôi ở đây (https://stackoverflow.com/questions/44159559/need-to-have-a-required-and-optional-fields-in-django-formset) – dungu

+0

@kedric Bạn đang hỏi anh chàng sai. Tôi đã không sử dụng Django kể từ ngay sau khi tôi đăng câu hỏi này. – mpen

+0

ooh, Được rồi cảm ơn vì phản hồi – dungu

Trả lời

65

tìm thấy một giải pháp tốt hơn:

class RequiredFormSet(BaseFormSet): 
    def __init__(self, *args, **kwargs): 
     super(RequiredFormSet, self).__init__(*args, **kwargs) 
     for form in self.forms: 
      form.empty_permitted = False 

Sau đó tạo formset của bạn như thế này:

MyFormSet = formset_factory(MyForm, formset=RequiredFormSet) 

tôi thực sự không biết tại sao điều này không phải là một lựa chọn để bắt đầu với .. nhưng, bất cứ điều gì. Tôi chỉ mất vài giờ để tìm ra.

Điều này sẽ làm cho tất cả các biểu mẫu được yêu cầu.Bạn chỉ có thể thực hiện yêu cầu đầu tiên bằng cách đặt self.forms[0].empty_permitted thành False.

+1

Đây là giải pháp cho một trong những phần khó chịu nhất của Django, không thể giải thích tại sao đây không phải là một phần của tài liệu – YPCrumble

+0

Vì lý do nào đó, tôi nhận được một keyError khi cố gắng thiết lập một biểu mẫu cụ thể để empty_permitted. Ví dụ: "form [0] .empty_permitted = False" đưa ra một lỗi. –

+0

@Zorpix Nên là 'self.forms [0]' Tôi nghĩ, giả sử bạn có ít nhất một biểu mẫu. – mpen

1

Ồ tôi nghĩ là tôi thấy. Hãy thử điều này:

from django.forms.formsets import BaseFormSet, formset_factory 
class OneExtraRequiredFormSet(BaseFormSet): 
    def initial_form_count(self): 
     return max(super(OneExtraRequiredFormSet,self).initial_form_count() - 1,0) 

VehicleFormSetFactory = formset_factory(VehicleForm, formset=OneExtraRequiredFormSet, extra=1) 

câu trả lời gốc == dưới ==

Khi bạn nói "ít nhất làm cho một hình thức yêu cầu", tôi giả sử bạn có nghĩa là "làm cho chỉ có một hình thức bổ sung cần thiết, bất kể có bao nhiêu có đã được thêm qua javascript ".

Bạn cần có đầu vào bị ẩn trên trang chứa số biểu mẫu đã được thêm qua javascript và sau đó sử dụng số đó, trừ 1, làm giá trị để chuyển thành thuộc tính extra cho hàm tạo biểu mẫu của bạn .

+0

Không hoàn toàn ... bỏ qua JavaScript hiện tại, một và chỉ một biểu mẫu được hiển thị (thêm = 1, không có dữ liệu ban đầu). Đó là * một * hình thức là không cần thiết - Tôi muốn nó được. Bất kỳ biểu mẫu nào được thêm qua JS nên * không * được yêu cầu, bao giờ hết. – mpen

+0

Bản chỉnh sửa của tôi có giúp ích không? – Wogan

+0

Điều đó có một số hành vi kỳ quái. Khi tôi để trống biểu mẫu và gửi biểu mẫu, nó thêm một biểu mẫu khác và đặt lỗi trên biểu mẫu mới và vẫn không xác thực biểu mẫu đầu tiên. – mpen

9

Vâng ... điều này làm cho biểu mẫu đầu tiên bắt buộc.

class RequiredFormSet(BaseFormSet): 
    def clean(self): 
     if any(self.errors): 
      return 
     if not self.forms[0].has_changed(): 
      raise forms.ValidationError('Please add at least one vehicle.') 

Chỉ "vấn đề" ở đây là nếu có 0 hình thức, sau đó phương pháp clean dường như không được gọi ở tất cả, vì vậy tôi không biết làm thế nào để kiểm tra xem có 0. Thực sự .. .Điều này sẽ không bao giờ xảy ra mặc dù (ngoại trừ việc JS của tôi có lỗi trong đó, cho phép bạn xóa tất cả các hình thức).

+1

Nếu bạn sử dụng biểu mẫu này để chỉnh sửa một bộ đối tượng hiện có, bạn sẽ luôn bị buộc phải cập nhật đối tượng đầu tiên. Điều này chỉ thích hợp cho việc tạo, không cập nhật. –

+0

@ Palm Palm, bạn có giải pháp không? Tôi cũng có cùng một vấn đề. –

Các vấn đề liên quan