2010-06-24 45 views
7

Tôi đang tìm phiên bản cập nhật của các Django SuperForms này. Có vẻ như không làm cho nó hoạt động ở Django 1.2. Đặc biệt, tôi muốn nó làm việc với ModelForms.Hợp chất Django/lồng nhau/biểu mẫu con?

Trường hợp sử dụng của tôi gần giống với của anh ấy; Tôi có một mô hình Address mà tôi muốn sử dụng làm biểu mẫu con ở nhiều nơi khác nhau. Đó là một nỗi đau để thử và kết hợp mọi thứ trong khung nhìn func.

+0

SuperForms phải làm gì? –

+0

Bạn về cơ bản muốn có một 'ModelForm' đi qua các phím nước ngoài? – sdolan

+0

@sdolan: Một cái gì đó như thế, vâng. Vâng, không * chỉ * đi qua các khóa ngoại, bởi vì sau đó các biểu mẫu con sẽ phải chỉ dựa trên biểu mẫu được tạo tự động được tạo ra từ mô hình. Tôi muốn có thể thực sự chọn một biểu mẫu khác (hoặc mẫu biểu mẫu) để nhúng. – mpen

Trả lời

5

Tôi đã cập nhật superforms.py làm việc w/1.2, và gắn nó vào vé bạn có liên quan đến: http://code.djangoproject.com/attachment/ticket/3706/superform.2.py

Có một dự án tôi đang làm việc trên có thể hưởng lợi từ điều này, vì vậy tôi figured tôi 'd dành thời gian và giúp bạn ra ngoài là tốt.

Hãy nhớ rằng tôi chỉ có công việc này với 1,2 /, và không thực sự cố gắng để làm sạch các bên trong. Bây giờ tôi có các trường hợp thử nghiệm chứng minh API, tôi có thể quay lại và làm sạch nó sau.

Nếu bạn đang sử dụng nó với ModelForms và bạn muốn lưu() chức năng bạn sẽ phải ghi đè lên phương thức trên lớp SuperForm của bạn.

Tôi hiện có địa phương trong vùng lưu trữ "phổ biến" của tôi với mã 90% bao gồm nhiều SubForms, SubForms hỗn hợp & biểu mẫu đã khai báo và ModelForms. Tôi đã bao gồm các trường hợp thử nghiệm dưới đây (hãy cẩn thận nó sử dụng lớp TestCaseBase của tôi, nhưng điều này sẽ cung cấp cho bạn ý chính của API). Hãy cho tôi biết nếu bạn có câu hỏi hoặc bất kỳ khu vực nào tôi đã bỏ lỡ.

from django_common.forms.superform import SuperForm, SubForm 
from django_common.test import TestCaseBase 
from django import forms 

class WhenSuperFormsIsUsedWithOnlySubForms(TestCaseBase): 
    def get_superform_with_forms(self, post_data=None): 
     class AddressForm(forms.Form): 
      street = forms.CharField(max_length=255) 
      city = forms.CharField(max_length=255) 

     class BusinessLocationForm(forms.Form): 
      phone_num = forms.CharField(max_length=255) 

     class TestSuperForm(SuperForm): 
      address = SubForm(AddressForm) 
      business_location = SubForm(BusinessLocationForm) 

     return TestSuperForm(data=post_data) 

    def should_not_be_valid_with_no_data(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_false(tsf.is_valid()) 

    def should_have_two_sub_forms(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(len(tsf.base_subforms), 2) 
     self.assert_equal(len(tsf.forms), 2) 

    def should_display_as_ul(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(tsf.as_ul(), '<li><label for="id_business_location-phone_num">Phone num:</label> <input id="id_business_location-phone_num" type="text" name="business_location-phone_num" maxlength="255" /></li>\n<li><label for="id_address-street">Street:</label> <input id="id_address-street" type="text" name="address-street" maxlength="255" /></li>\n<li><label for="id_address-city">City:</label> <input id="id_address-city" type="text" name="address-city" maxlength="255" /></li>') 

    def should_display_as_table(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(tsf.as_table(), '<tr><th><label for="id_business_location-phone_num">Phone num:</label></th><td><input id="id_business_location-phone_num" type="text" name="business_location-phone_num" maxlength="255" /></td></tr>\n<tr><th><label for="id_address-street">Street:</label></th><td><input id="id_address-street" type="text" name="address-street" maxlength="255" /></td></tr>\n<tr><th><label for="id_address-city">City:</label></th><td><input id="id_address-city" type="text" name="address-city" maxlength="255" /></td></tr>') 

    def should_display_as_p(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(tsf.as_p(), '<p><label for="id_business_location-phone_num">Phone num:</label> <input id="id_business_location-phone_num" type="text" name="business_location-phone_num" maxlength="255" /></p>\n<p><label for="id_address-street">Street:</label> <input id="id_address-street" type="text" name="address-street" maxlength="255" /></p>\n<p><label for="id_address-city">City:</label> <input id="id_address-city" type="text" name="address-city" maxlength="255" /></p>') 

    def should_display_as_table_with_unicode(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(tsf.__unicode__(), tsf.as_table()) 

    def should_be_valid_if_good_data(self): 
     data = { 
      'business_location-phone_num' : '8055551234', 
      'address-street' : '1234 Street Dr.', 
      'address-city' : 'Santa Barbara', 
     } 
     tsf = self.get_superform_with_forms(data) 
     self.assert_true(tsf.is_valid()) 
     self.assert_equal(tsf.cleaned_data['business_location']['phone_num'], 
          '8055551234') 
     self.assert_equal(tsf.cleaned_data['address']['street'], '1234 Street Dr.') 
     self.assert_equal(tsf.cleaned_data['address']['city'], 'Santa Barbara') 

    def should_be_invalid_if_missing_data(self): 
     data = { 
      'business_location-phone_num' : '8055551234', 
      'address-street' : '1234 Street Dr.', 
     } 
     tsf = self.get_superform_with_forms(data) 
     self.assert_false(tsf.is_valid()) 

     self.assert_false(tsf.errors['business_location']) 
     self.assert_true(tsf.errors['address']) 
     self.assert_equal(tsf.errors['address']['city'], ['This field is required.']) 

    def should_be_invalid_if_invalid_data(self): 
     data = { 
      'business_location-phone_num' : '8055551234', 
      'address-street' : '1234 Street Dr.', 
      'address-city' : '', 
     } 
     tsf = self.get_superform_with_forms(data) 
     self.assert_false(tsf.is_valid()) 


class WhenSuperformsIsUsedWithSubFormsAndDeclaredFields(TestCaseBase): 
    """Some basic sanity checks that working with fields combined with SubForms works.""" 
    def get_superform_with_forms(self, post_data=None): 
     class AddressForm(forms.Form): 
      street = forms.CharField(max_length=255) 

     class TestSuperForm(SuperForm): 
      name = forms.CharField(max_length=255) 
      address = SubForm(AddressForm) 

     return TestSuperForm(data=post_data) 

    def should_not_be_valid_with_no_data(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_false(tsf.is_valid()) 

    def should_have_two_forms_and_a_single_subform(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(len(tsf.base_subforms), 1) 
     self.assert_equal(len(tsf.forms), 2) 

    def should_print_as_table(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(tsf.as_table(), '<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="255" /></td></tr>\n<tr><th><label for="id_address-street">Street:</label></th><td><input id="id_address-street" type="text" name="address-street" maxlength="255" /></td></tr>') 

    def should_validate_when_fields_exist(self): 
     data = { 
      'name': 'Sam', 
      'address-street': 'Some Street', 
     } 
     tsf = self.get_superform_with_forms(data) 
     self.assert_true(tsf.is_valid()) 

     self.assert_equal(tsf.cleaned_data['name'], 'Sam') 
     self.assert_equal(tsf.cleaned_data['address']['street'], 'Some Street') 

    def should_not_validate_with_invalid_data(self): 
     data = { 
      'name': '', 
      'address-street': 'Some Street', 
     } 
     tsf = self.get_superform_with_forms(data) 
     self.assert_false(tsf.is_valid()) 

     self.assert_equal(tsf.errors['name'], ['This field is required.']) 



class WhenSuperformsIsUsedWithModelForms(TestCaseBase): 
    def get_superform_with_forms(self, post_data=None): 
     from django.db import models 
     class Address(models.Model): 
      city = models.CharField(max_length=255) 

     class AddressForm(forms.ModelForm): 
      class Meta: 
       model = Address 

     class TestSuperForm(SuperForm): 
      address = SubForm(AddressForm) 

     return TestSuperForm(data=post_data) 

    def should_not_be_valid_with_no_data(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_false(tsf.is_valid()) 

    def should_have_two_forms_and_a_single_subform(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(len(tsf.base_subforms), 1) 
     self.assert_equal(len(tsf.forms), 1) 

    def should_print_as_table(self): 
     tsf = self.get_superform_with_forms() 
     self.assert_equal(tsf.as_table(), '<tr><th><label for="id_address-city">City:</label></th><td><input id="id_address-city" type="text" name="address-city" maxlength="255" /></td></tr>') 

    def should_validate_when_fields_exist(self): 
     data = { 
      'address-city': 'Some City', 
     } 
     tsf = self.get_superform_with_forms(data) 
     self.assert_true(tsf.is_valid()) 

     self.assert_equal(tsf.cleaned_data['address']['city'], 'Some City') 

    def should_not_validate_with_invalid_data(self): 
     data = { 
      'address-city': '', 
     } 
     tsf = self.get_superform_with_forms(data) 
     self.assert_false(tsf.is_valid()) 

     self.assert_equal(tsf.errors['address']['city'], ['This field is required.']) 

Tận hưởng!

+0

Thật tuyệt vời! Cảm ơn bạn rất nhiều :) Thật không may này đến một chút muộn cho dự án hiện tại của tôi (tìm thấy một sol'n), nhưng có lẽ cho một kế tiếp của tôi! – mpen

+0

Vâng, không sao cả. Cảm ơn bạn đã đặt câu hỏi và đưa ra một điểm khởi đầu tốt. Đây là thứ có thể hữu ích cho tôi trong một thời gian dài. Đối với giải pháp khác của bạn, bạn sẽ làm gì? Ồ, tôi có kiếm được tiền thưởng không? :) – sdolan

+0

Bạn chắc chắn đã làm. Tôi giả sử mã của bạn thực sự hoạt động;) Tôi đã làm gì? Chỉ có điều ngu ngốc nhất mà một lập trình viên có thể làm! Viết lại toàn bộ * biểu mẫu * ứng dụng từ đầu! – mpen

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