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. |