2010-06-24 2 views
7

Я ищу обновленную версию этих Django SuperForms. Кажется, он не может работать в Django 1.2. В частности, мне бы хотелось, чтобы он работал с ModelForms.Состав Django/вложенные/подформы?

Мой прецедент почти идентичен его; У меня есть модель Address, которую я бы хотел использовать в качестве подформы в разных местах. Это боль, чтобы попытаться объединить все в функции func.

+0

Что должны делать SuperForms? –

+0

Вы в основном хотите, чтобы модель ModelForm пересекала внешние ключи? – sdolan

+0

@sdolan: Что-то вроде этого, да. Ну, а не * просто * пересекают внешние ключи, потому что тогда подчиненные формы должны быть основаны исключительно на автоматически созданной форме, созданной с помощью модели. Я бы хотел, чтобы на самом деле выбрать другую форму (или модель) для вставки. – mpen

ответ

5

Я обновил superforms.py работать ж/1.2, и прикрепил его к билету вы связаны с: http://code.djangoproject.com/attachment/ticket/3706/superform.2.py

Там есть проект, я работаю над, которые могли бы извлечь выгоду из этого, поэтому я решил «Проведите время и помогите вам.

Имейте в виду, что я только что получил это, чтобы работать с 1.2, и на самом деле не пытался очистить внутренности. Теперь, когда у меня есть тестовые примеры, доказывающие API, я могу вернуться и убрать это позже.

Если вы используете его с ModelForms, и вам нужна функция save(), вам придется переопределить метод в вашем классе SuperForm.

В настоящее время я располагаю локально в своем «общем» хранилище с ~ 90% охватом кода, который охватывает несколько субформформ, смешанных субформатов & объявленных форм и ModelForms. Я включил тестовые примеры ниже (остерегайтесь, что он использует мой класс TestCaseBase, но это должно дать вам суть API). Дайте мне знать, если у вас есть вопросы или какие-то области, которые я пропустил.

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.']) 

Наслаждайтесь!

+0

Ничего себе, это здорово! Большое вам спасибо :) К сожалению, это немного опоздало для моего текущего проекта (нашлось другое sol'n), но, возможно, для моего следующего! – mpen

+0

Да, без проблем. Спасибо, что поставили вопрос и дали хорошую отправную точку. Это то, что было бы полезно для меня в течение длительного времени. Что касается вашего другого решения, что вы делаете? О, и я зарабатывал щедрость? :) – sdolan

+0

Вы уверены. Я предполагаю, что ваш код действительно работает;) Что я в итоге сделал? Только самая тупая вещь, которую может сделать программист! Снова переписал приложение * whole * forms с нуля! – mpen