1
0
mirror of https://github.com/django/django.git synced 2025-10-23 21:59:11 +00:00

Fixed #19733 - deprecated ModelForms without 'fields' or 'exclude', and added '__all__' shortcut

This also updates all dependent functionality, including modelform_factory
 and modelformset_factory, and the generic views `ModelFormMixin`,
 `CreateView` and `UpdateView` which gain a new `fields` attribute.
This commit is contained in:
Luke Plant
2013-02-21 21:56:55 +00:00
parent 1e37cb37ce
commit f026a519ae
34 changed files with 578 additions and 201 deletions

View File

@@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals
import datetime
import os
from decimal import Decimal
import warnings
from django import forms
from django.core.exceptions import FieldError
@@ -30,19 +31,25 @@ if test_images:
class ImageFileForm(forms.ModelForm):
class Meta:
model = ImageFile
fields = '__all__'
class OptionalImageFileForm(forms.ModelForm):
class Meta:
model = OptionalImageFile
fields = '__all__'
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = '__all__'
class PriceForm(forms.ModelForm):
class Meta:
model = Price
fields = '__all__'
class BookForm(forms.ModelForm):
@@ -66,11 +73,13 @@ class ExplicitPKForm(forms.ModelForm):
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
class DerivedPostForm(forms.ModelForm):
class Meta:
model = DerivedPost
fields = '__all__'
class CustomAuthorForm(forms.ModelForm):
@@ -78,61 +87,79 @@ class CustomAuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = '__all__'
class FlexDatePostForm(forms.ModelForm):
class Meta:
model = FlexibleDatePost
fields = '__all__'
class BaseCategoryForm(forms.ModelForm):
class Meta:
model = Category
fields = '__all__'
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = '__all__'
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = '__all__'
class PartialArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ('headline','pub_date')
class RoykoForm(forms.ModelForm):
class Meta:
model = Author
fields = '__all__'
class TestArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = '__all__'
class PartialArticleFormWithSlug(forms.ModelForm):
class Meta:
model = Article
fields=('headline', 'slug', 'pub_date')
fields = ('headline', 'slug', 'pub_date')
class ArticleStatusForm(forms.ModelForm):
class Meta:
model = ArticleStatus
fields = '__all__'
class InventoryForm(forms.ModelForm):
class Meta:
model = Inventory
fields = '__all__'
class SelectInventoryForm(forms.Form):
items = forms.ModelMultipleChoiceField(Inventory.objects.all(), to_field_name='barcode')
class CustomFieldForExclusionForm(forms.ModelForm):
class Meta:
model = CustomFieldForExclusionModel
fields = ['name', 'markup']
class ShortCategory(forms.ModelForm):
name = forms.CharField(max_length=5)
slug = forms.CharField(max_length=5)
@@ -140,30 +167,44 @@ class ShortCategory(forms.ModelForm):
class Meta:
model = Category
fields = '__all__'
class ImprovedArticleForm(forms.ModelForm):
class Meta:
model = ImprovedArticle
fields = '__all__'
class ImprovedArticleWithParentLinkForm(forms.ModelForm):
class Meta:
model = ImprovedArticleWithParentLink
fields = '__all__'
class BetterAuthorForm(forms.ModelForm):
class Meta:
model = BetterAuthor
fields = '__all__'
class AuthorProfileForm(forms.ModelForm):
class Meta:
model = AuthorProfile
fields = '__all__'
class TextFileForm(forms.ModelForm):
class Meta:
model = TextFile
fields = '__all__'
class BigIntForm(forms.ModelForm):
class Meta:
model = BigInt
fields = '__all__'
class ModelFormWithMedia(forms.ModelForm):
class Media:
@@ -173,19 +214,25 @@ class ModelFormWithMedia(forms.ModelForm):
}
class Meta:
model = TextFile
fields = '__all__'
class CommaSeparatedIntegerForm(forms.ModelForm):
class Meta:
model = CommaSeparatedInteger
class Meta:
model = CommaSeparatedInteger
fields = '__all__'
class PriceFormWithoutQuantity(forms.ModelForm):
class Meta:
model = Price
exclude = ('quantity',)
class ColourfulItemForm(forms.ModelForm):
class Meta:
model = ColourfulItem
fields = '__all__'
class ModelFormBaseTest(TestCase):
@@ -193,6 +240,25 @@ class ModelFormBaseTest(TestCase):
self.assertEqual(list(BaseCategoryForm.base_fields),
['name', 'slug', 'url'])
def test_missing_fields_attribute(self):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always", PendingDeprecationWarning)
class MissingFieldsForm(forms.ModelForm):
class Meta:
model = Category
# There is some internal state in warnings module which means that
# if a warning has been seen already, the catch_warnings won't
# have recorded it. The following line therefore will not work reliably:
# self.assertEqual(w[0].category, PendingDeprecationWarning)
# Until end of the deprecation cycle, should still create the
# form as before:
self.assertEqual(list(MissingFieldsForm.base_fields),
['name', 'slug', 'url'])
def test_extra_fields(self):
class ExtraFields(BaseCategoryForm):
some_extra_field = forms.BooleanField()
@@ -206,6 +272,33 @@ class ModelFormBaseTest(TestCase):
class Meta:
model = Category
fields = '__all__'
self.assertTrue(isinstance(ReplaceField.base_fields['url'],
forms.fields.BooleanField))
def test_replace_field_variant_2(self):
# Should have the same result as before,
# but 'fields' attribute specified differently
class ReplaceField(forms.ModelForm):
url = forms.BooleanField()
class Meta:
model = Category
fields = ['url']
self.assertTrue(isinstance(ReplaceField.base_fields['url'],
forms.fields.BooleanField))
def test_replace_field_variant_3(self):
# Should have the same result as before,
# but 'fields' attribute specified differently
class ReplaceField(forms.ModelForm):
url = forms.BooleanField()
class Meta:
model = Category
fields = [] # url will still appear, since it is explicit above
self.assertTrue(isinstance(ReplaceField.base_fields['url'],
forms.fields.BooleanField))
@@ -216,19 +309,11 @@ class ModelFormBaseTest(TestCase):
class Meta:
model = Author
fields = '__all__'
wf = AuthorForm({'name': 'Richard Lockridge'})
self.assertTrue(wf.is_valid())
def test_limit_fields(self):
class LimitFields(forms.ModelForm):
class Meta:
model = Category
fields = ['url']
self.assertEqual(list(LimitFields.base_fields),
['url'])
def test_limit_nonexistent_field(self):
expected_msg = 'Unknown field(s) (nonexistent) specified for Category'
with self.assertRaisesMessage(FieldError, expected_msg):
@@ -294,6 +379,7 @@ class ModelFormBaseTest(TestCase):
"""
class Meta:
model = Article
fields = '__all__'
# MixModelForm is now an Article-related thing, because MixModelForm.Meta
# overrides BaseCategoryForm.Meta.
@@ -348,6 +434,7 @@ class ModelFormBaseTest(TestCase):
class Meta:
model = Category
fields = '__all__'
class SubclassMeta(SomeCategoryForm):
""" We can also subclass the Meta inner class to change the fields