From 4bcc3a65c60bacca46121cb7a156174cb69e9bbf Mon Sep 17 00:00:00 2001
From: Daniel Barreto <daniel@gia.usb.ve>
Date: Sat, 12 Nov 2011 20:33:43 -0430
Subject: [PATCH] Fixes #15877 -- ModelForm will raise ValueError if not Meta model specified.
---
 django/forms/models.py                |    4 ++--
 tests/modeltests/model_forms/tests.py |   26 +++++++++++---------------
 2 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/django/forms/models.py b/django/forms/models.py
index b65f067..a9d4129 100644
      
        
          
        
        
          
            | a | b | class BaseModelForm(BaseForm): | 
        
        
          
            | 227 | 227 | initial=None, error_class=ErrorList, label_suffix=':', | 
          
            | 228 | 228 | empty_permitted=False, instance=None): | 
          
            | 229 | 229 | opts = self._meta | 
        
        
          
            |  | 230 | if opts.model is None: | 
          
            |  | 231 | raise ValueError('ModelForm has no model class specified.') | 
        
        
          
            | 230 | 232 | if instance is None: | 
        
        
          
            | 231 |  |             if opts.model is None: | 
          
            | 232 |  |                 raise ValueError('ModelForm has no model class specified.') | 
        
        
          
            | 233 | 233 | # if we didn't get an instance, instantiate a new one | 
          
            | 234 | 234 | self.instance = opts.model() | 
          
            | 235 | 235 | object_data = {} | 
        
      
    
    
      
      diff --git a/tests/modeltests/model_forms/tests.py b/tests/modeltests/model_forms/tests.py
index c4abdbb..bb288ed 100644
      
        
          
        
        
          
            | a | b | class CustomFieldForExclusionForm(forms.ModelForm): | 
        
        
          
            | 124 | 124 | model = CustomFieldForExclusionModel | 
          
            | 125 | 125 | fields = ['name', 'markup'] | 
          
            | 126 | 126 |  | 
        
        
          
            | 127 |  | class ShortCategory(forms.ModelForm): | 
          
            | 128 |  |     name = forms.CharField(max_length=5) | 
          
            | 129 |  |     slug = forms.CharField(max_length=5) | 
          
            | 130 |  |     url = forms.CharField(max_length=3) | 
          
            | 131 |  |  | 
        
        
          
            | 132 | 127 | class ImprovedArticleForm(forms.ModelForm): | 
          
            | 133 | 128 | class Meta: | 
          
            | 134 | 129 | model = ImprovedArticle | 
        
        
          
            | … | … | class ModelFormBaseTest(TestCase): | 
        
        
          
            | 181 | 176 | self.assertEqual(BaseCategoryForm.base_fields.keys(), | 
          
            | 182 | 177 | ['name', 'slug', 'url']) | 
          
            | 183 | 178 |  | 
        
        
          
            |  | 179 | def test_invalid_meta_model(self): | 
          
            |  | 180 | class InvalidModelForm(forms.ModelForm): | 
          
            |  | 181 | class Meta: | 
          
            |  | 182 | pass # no model. | 
          
            |  | 183 | # can't create new form | 
          
            |  | 184 | with self.assertRaises(ValueError): | 
          
            |  | 185 | f = InvalidModelForm() | 
          
            |  | 186 | # even if you provide a model instance | 
          
            |  | 187 | with self.assertRaises(ValueError): | 
          
            |  | 188 | f = InvalidModelForm(instance=Category) | 
          
            |  | 189 |  | 
        
        
          
            | 184 | 190 | def test_extra_fields(self): | 
          
            | 185 | 191 | class ExtraFields(BaseCategoryForm): | 
          
            | 186 | 192 | some_extra_field = forms.BooleanField() | 
        
        
          
            | … | … | class OldFormForXTests(TestCase): | 
        
        
          
            | 863 | 869 | f.save_m2m() | 
          
            | 864 | 870 | self.assertEqual(map(lambda o: o.name, new_art.categories.order_by('name')), ["Entertainment", "It's a test"]) | 
          
            | 865 | 871 |  | 
        
        
          
            | 866 |  |         # Here, we define a custom ModelForm. Because it happens to have the same fields as | 
          
            | 867 |  |         # the Category model, we can just call the form's save() to apply its changes to an | 
          
            | 868 |  |         # existing Category instance. | 
          
            | 869 |  |         cat = Category.objects.get(name='Third test') | 
          
            | 870 |  |         self.assertEqual(cat.name, "Third test") | 
          
            | 871 |  |         self.assertEqual(cat.id == c3.id, True) | 
          
            | 872 |  |         form = ShortCategory({'name': 'Third', 'slug': 'third', 'url': '3rd'}, instance=cat) | 
          
            | 873 |  |         self.assertEqual(form.save().name, 'Third') | 
          
            | 874 |  |         self.assertEqual(Category.objects.get(id=c3.id).name, 'Third') | 
          
            | 875 |  |  | 
        
        
          
            | 876 | 872 | # Here, we demonstrate that choices for a ForeignKey ChoiceField are determined | 
          
            | 877 | 873 | # at runtime, based on the data in the database when the form is displayed, not | 
          
            | 878 | 874 | # the data in the database when the form is instantiated. |