mirror of
https://github.com/django/django.git
synced 2025-10-24 22:26:08 +00:00
Merge branch 'master' into schema-alteration
This commit is contained in:
@@ -14,7 +14,8 @@ import subprocess
|
||||
import sys
|
||||
import codecs
|
||||
|
||||
from django import conf, bin, get_version
|
||||
import django
|
||||
from django import conf, get_version
|
||||
from django.conf import settings
|
||||
from django.core.management import BaseCommand, CommandError
|
||||
from django.db import connection
|
||||
@@ -149,8 +150,8 @@ class AdminScriptTestCase(unittest.TestCase):
|
||||
return out, err
|
||||
|
||||
def run_django_admin(self, args, settings_file=None):
|
||||
bin_dir = os.path.abspath(os.path.dirname(upath(bin.__file__)))
|
||||
return self.run_test(os.path.join(bin_dir, 'django-admin.py'), args, settings_file)
|
||||
script_dir = os.path.abspath(os.path.join(os.path.dirname(upath(django.__file__)), 'bin'))
|
||||
return self.run_test(os.path.join(script_dir, 'django-admin.py'), args, settings_file)
|
||||
|
||||
def run_manage(self, args, settings_file=None):
|
||||
def safe_remove(path):
|
||||
|
||||
@@ -16,10 +16,6 @@ class ValidFields(admin.ModelAdmin):
|
||||
form = SongForm
|
||||
fields = ['title']
|
||||
|
||||
class InvalidFields(admin.ModelAdmin):
|
||||
form = SongForm
|
||||
fields = ['spam']
|
||||
|
||||
class ValidFormFieldsets(admin.ModelAdmin):
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
class ExtraFieldForm(SongForm):
|
||||
@@ -49,10 +45,6 @@ class ValidationTestCase(TestCase):
|
||||
# Regression test for #8027: custom ModelForms with fields/fieldsets
|
||||
"""
|
||||
validate(ValidFields, Song)
|
||||
self.assertRaisesMessage(ImproperlyConfigured,
|
||||
"'InvalidFields.fields' refers to field 'spam' that is missing from the form.",
|
||||
validate,
|
||||
InvalidFields, Song)
|
||||
|
||||
def test_custom_get_form_with_fieldsets(self):
|
||||
"""
|
||||
@@ -277,8 +269,6 @@ class ValidationTestCase(TestCase):
|
||||
"""
|
||||
class SongForm(forms.ModelForm):
|
||||
extra_data = forms.CharField()
|
||||
class Meta:
|
||||
model = Song
|
||||
|
||||
class FieldsOnFormOnlyAdmin(admin.ModelAdmin):
|
||||
form = SongForm
|
||||
@@ -295,6 +285,8 @@ class ValidationTestCase(TestCase):
|
||||
extra_data = forms.CharField()
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class FieldsOnFormOnlyAdmin(admin.ModelAdmin):
|
||||
form = SongForm
|
||||
|
||||
@@ -25,3 +25,4 @@ class Photo(models.Model):
|
||||
class PhotoForm(ModelForm):
|
||||
class Meta:
|
||||
model = Photo
|
||||
fields = '__all__'
|
||||
|
||||
@@ -322,6 +322,7 @@ class FormsTests(TestCase):
|
||||
class ArticleForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = '__all__'
|
||||
|
||||
def test_foreign_object_form(self):
|
||||
# A very crude test checking that the non-concrete fields do not get form fields.
|
||||
|
||||
@@ -139,6 +139,7 @@ class FormsRegressionsTestCase(TestCase):
|
||||
class CheeseForm(ModelForm):
|
||||
class Meta:
|
||||
model = Cheese
|
||||
fields = '__all__'
|
||||
|
||||
form = CheeseForm({
|
||||
'name': 'Brie',
|
||||
|
||||
@@ -17,11 +17,13 @@ from ..models import (ChoiceOptionModel, ChoiceFieldModel, FileModel, Group,
|
||||
class ChoiceFieldForm(ModelForm):
|
||||
class Meta:
|
||||
model = ChoiceFieldModel
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class OptionalMultiChoiceModelForm(ModelForm):
|
||||
class Meta:
|
||||
model = OptionalMultiChoiceModel
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class FileForm(Form):
|
||||
@@ -139,6 +141,7 @@ class FormsModelTestCase(TestCase):
|
||||
class BoundaryForm(ModelForm):
|
||||
class Meta:
|
||||
model = BoundaryModel
|
||||
fields = '__all__'
|
||||
|
||||
f = BoundaryForm({'positive_integer': 100})
|
||||
self.assertTrue(f.is_valid())
|
||||
@@ -154,6 +157,7 @@ class FormsModelTestCase(TestCase):
|
||||
class DefaultsForm(ModelForm):
|
||||
class Meta:
|
||||
model = Defaults
|
||||
fields = '__all__'
|
||||
|
||||
self.assertEqual(DefaultsForm().fields['name'].initial, 'class default value')
|
||||
self.assertEqual(DefaultsForm().fields['def_date'].initial, datetime.date(1980, 1, 1))
|
||||
|
||||
@@ -247,6 +247,7 @@ class CustomWidget(forms.TextInput):
|
||||
class TaggedItemForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = TaggedItem
|
||||
fields = '__all__'
|
||||
widgets = {'tag': CustomWidget}
|
||||
|
||||
class GenericInlineFormsetTest(TestCase):
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import warnings
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.core.urlresolvers import reverse
|
||||
from django import forms
|
||||
from django.test import TestCase
|
||||
from django.utils.unittest import expectedFailure
|
||||
from django.views.generic.base import View
|
||||
from django.views.generic.edit import FormMixin
|
||||
from django.views.generic.edit import FormMixin, CreateView, UpdateView
|
||||
|
||||
from . import views
|
||||
from .models import Artist, Author
|
||||
@@ -34,6 +36,7 @@ class ModelFormMixinTests(TestCase):
|
||||
form_class = views.AuthorGetQuerySetFormView().get_form_class()
|
||||
self.assertEqual(form_class._meta.model, Author)
|
||||
|
||||
|
||||
class CreateViewTests(TestCase):
|
||||
urls = 'generic_views.urls'
|
||||
|
||||
@@ -112,6 +115,45 @@ class CreateViewTests(TestCase):
|
||||
self.assertEqual(res.status_code, 302)
|
||||
self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/')
|
||||
|
||||
def test_create_view_with_restricted_fields(self):
|
||||
|
||||
class MyCreateView(CreateView):
|
||||
model = Author
|
||||
fields = ['name']
|
||||
|
||||
self.assertEqual(list(MyCreateView().get_form_class().base_fields),
|
||||
['name'])
|
||||
|
||||
def test_create_view_all_fields(self):
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always", PendingDeprecationWarning)
|
||||
|
||||
class MyCreateView(CreateView):
|
||||
model = Author
|
||||
fields = '__all__'
|
||||
|
||||
self.assertEqual(list(MyCreateView().get_form_class().base_fields),
|
||||
['name', 'slug'])
|
||||
self.assertEqual(len(w), 0)
|
||||
|
||||
|
||||
def test_create_view_without_explicit_fields(self):
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always", PendingDeprecationWarning)
|
||||
|
||||
class MyCreateView(CreateView):
|
||||
model = Author
|
||||
|
||||
# Until end of the deprecation cycle, should still create the form
|
||||
# as before:
|
||||
self.assertEqual(list(MyCreateView().get_form_class().base_fields),
|
||||
['name', 'slug'])
|
||||
|
||||
# but with a warning:
|
||||
self.assertEqual(w[0].category, PendingDeprecationWarning)
|
||||
|
||||
|
||||
class UpdateViewTests(TestCase):
|
||||
urls = 'generic_views.urls'
|
||||
|
||||
@@ -11,6 +11,7 @@ class AuthorForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Author
|
||||
fields = ['name', 'slug']
|
||||
|
||||
|
||||
class ContactForm(forms.Form):
|
||||
|
||||
@@ -85,15 +85,18 @@ class ContactView(generic.FormView):
|
||||
|
||||
class ArtistCreate(generic.CreateView):
|
||||
model = Artist
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class NaiveAuthorCreate(generic.CreateView):
|
||||
queryset = Author.objects.all()
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class AuthorCreate(generic.CreateView):
|
||||
model = Author
|
||||
success_url = '/list/authors/'
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class SpecializedAuthorCreate(generic.CreateView):
|
||||
@@ -112,19 +115,23 @@ class AuthorCreateRestricted(AuthorCreate):
|
||||
|
||||
class ArtistUpdate(generic.UpdateView):
|
||||
model = Artist
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class NaiveAuthorUpdate(generic.UpdateView):
|
||||
queryset = Author.objects.all()
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class AuthorUpdate(generic.UpdateView):
|
||||
model = Author
|
||||
success_url = '/list/authors/'
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class OneAuthorUpdate(generic.UpdateView):
|
||||
success_url = '/list/authors/'
|
||||
fields = '__all__'
|
||||
|
||||
def get_object(self):
|
||||
return Author.objects.get(pk=1)
|
||||
@@ -184,6 +191,8 @@ class BookDetail(BookConfig, generic.DateDetailView):
|
||||
pass
|
||||
|
||||
class AuthorGetQuerySetFormView(generic.edit.ModelFormMixin):
|
||||
fields = '__all__'
|
||||
|
||||
def get_queryset(self):
|
||||
return Author.objects.all()
|
||||
|
||||
|
||||
@@ -24,3 +24,7 @@ class Person(models.Model):
|
||||
class ManualPrimaryKeyTest(models.Model):
|
||||
id = models.IntegerField(primary_key=True)
|
||||
data = models.CharField(max_length=100)
|
||||
|
||||
|
||||
class Profile(models.Model):
|
||||
person = models.ForeignKey(Person, primary_key=True)
|
||||
|
||||
@@ -4,9 +4,9 @@ from datetime import date
|
||||
import traceback
|
||||
|
||||
from django.db import IntegrityError
|
||||
from django.test import TestCase
|
||||
from django.test import TestCase, TransactionTestCase
|
||||
|
||||
from .models import Person, ManualPrimaryKeyTest
|
||||
from .models import Person, ManualPrimaryKeyTest, Profile
|
||||
|
||||
|
||||
class GetOrCreateTests(TestCase):
|
||||
@@ -64,3 +64,16 @@ class GetOrCreateTests(TestCase):
|
||||
formatted_traceback = traceback.format_exc()
|
||||
self.assertIn('obj.save', formatted_traceback)
|
||||
|
||||
|
||||
class GetOrCreateTransactionTests(TransactionTestCase):
|
||||
|
||||
def test_get_or_create_integrityerror(self):
|
||||
# Regression test for #15117. Requires a TransactionTestCase on
|
||||
# databases that delay integrity checks until the end of transactions,
|
||||
# otherwise the exception is never raised.
|
||||
try:
|
||||
Profile.objects.get_or_create(person=Person(id=1))
|
||||
except IntegrityError:
|
||||
pass
|
||||
else:
|
||||
self.skipTest("This backend does not support integrity checks.")
|
||||
|
||||
@@ -30,6 +30,10 @@ class ExtractorTests(SimpleTestCase):
|
||||
return
|
||||
shutil.rmtree(dname)
|
||||
|
||||
def rmfile(self, filepath):
|
||||
if os.path.exists(filepath):
|
||||
os.remove(filepath)
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.test_dir)
|
||||
try:
|
||||
@@ -126,18 +130,22 @@ class BasicExtractorTests(ExtractorTests):
|
||||
# Check that the temporary file was cleaned up
|
||||
self.assertFalse(os.path.exists('./templates/template_with_error.tpl.py'))
|
||||
|
||||
def test_unicode_decode_error(self):
|
||||
os.chdir(self.test_dir)
|
||||
shutil.copyfile('./not_utf8.sample', './not_utf8.txt')
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'not_utf8.txt'))
|
||||
stdout = StringIO()
|
||||
management.call_command('makemessages', locale=LOCALE, stdout=stdout)
|
||||
self.assertIn("UnicodeDecodeError: skipped file not_utf8.txt in .",
|
||||
force_text(stdout.getvalue()))
|
||||
|
||||
def test_extraction_warning(self):
|
||||
"""test xgettext warning about multiple bare interpolation placeholders"""
|
||||
os.chdir(self.test_dir)
|
||||
shutil.copyfile('./code.sample', './code_sample.py')
|
||||
self.addCleanup(self.rmfile, os.path.join(self.test_dir, 'code_sample.py'))
|
||||
stdout = StringIO()
|
||||
try:
|
||||
management.call_command('makemessages', locale=LOCALE, stdout=stdout)
|
||||
finally:
|
||||
try:
|
||||
os.remove('./code_sample.py')
|
||||
except OSError:
|
||||
pass
|
||||
management.call_command('makemessages', locale=LOCALE, stdout=stdout)
|
||||
self.assertIn("code_sample.py:4", force_text(stdout.getvalue()))
|
||||
|
||||
def test_template_message_context_extractor(self):
|
||||
|
||||
1
tests/i18n/commands/not_utf8.sample
Normal file
1
tests/i18n/commands/not_utf8.sample
Normal file
@@ -0,0 +1 @@
|
||||
Copyright (c) 2009 <20>yvind Sean Kinsey, oyvind@kinsey.no
|
||||
@@ -24,3 +24,4 @@ class CompanyForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Company
|
||||
fields = '__all__'
|
||||
|
||||
@@ -10,7 +10,7 @@ from .models import Poet, Poem, School, Parent, Child
|
||||
class DeletionTests(TestCase):
|
||||
|
||||
def test_deletion(self):
|
||||
PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
|
||||
PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True, fields="__all__")
|
||||
poet = Poet.objects.create(name='test')
|
||||
poem = poet.poem_set.create(name='test poem')
|
||||
data = {
|
||||
@@ -32,7 +32,7 @@ class DeletionTests(TestCase):
|
||||
Make sure that an add form that is filled out, but marked for deletion
|
||||
doesn't cause validation errors.
|
||||
"""
|
||||
PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
|
||||
PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True, fields="__all__")
|
||||
poet = Poet.objects.create(name='test')
|
||||
data = {
|
||||
'poem_set-TOTAL_FORMS': '1',
|
||||
@@ -60,7 +60,7 @@ class DeletionTests(TestCase):
|
||||
Make sure that a change form that is filled out, but marked for deletion
|
||||
doesn't cause validation errors.
|
||||
"""
|
||||
PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
|
||||
PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True, fields="__all__")
|
||||
poet = Poet.objects.create(name='test')
|
||||
poem = poet.poem_set.create(name='test poem')
|
||||
data = {
|
||||
@@ -115,8 +115,8 @@ class InlineFormsetFactoryTest(TestCase):
|
||||
"""
|
||||
These should both work without a problem.
|
||||
"""
|
||||
inlineformset_factory(Parent, Child, fk_name='mother')
|
||||
inlineformset_factory(Parent, Child, fk_name='father')
|
||||
inlineformset_factory(Parent, Child, fk_name='mother', fields="__all__")
|
||||
inlineformset_factory(Parent, Child, fk_name='father', fields="__all__")
|
||||
|
||||
def test_exception_on_unspecified_foreign_key(self):
|
||||
"""
|
||||
|
||||
@@ -60,10 +60,6 @@ class ManyToOneRegressionTests(TestCase):
|
||||
self.assertRaises(ValueError, Child, name='xyzzy', parent=None)
|
||||
self.assertRaises(ValueError, Child.objects.create, name='xyzzy', parent=None)
|
||||
|
||||
# Trying to assign to unbound attribute raises AttributeError
|
||||
six.assertRaisesRegex(self, AttributeError, "must be accessed via instance",
|
||||
Child.parent.__set__, None, p)
|
||||
|
||||
# Creation using keyword argument should cache the related object.
|
||||
p = Parent.objects.get(name="Parent")
|
||||
c = Child(parent=p)
|
||||
|
||||
@@ -6,7 +6,7 @@ from decimal import Decimal
|
||||
from django import test
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models, IntegrityError
|
||||
from django.db import connection, models, IntegrityError
|
||||
from django.db.models.fields.files import FieldFile
|
||||
from django.utils import six
|
||||
from django.utils import unittest
|
||||
@@ -455,6 +455,10 @@ class BinaryFieldTests(test.TestCase):
|
||||
# Test default value
|
||||
self.assertEqual(bytes(dm.short_data), b'\x08')
|
||||
|
||||
if connection.vendor == 'mysql' and six.PY3:
|
||||
# Existing MySQL DB-API drivers fail on binary data.
|
||||
test_set_and_retrieve = unittest.expectedFailure(test_set_and_retrieve)
|
||||
|
||||
def test_max_length(self):
|
||||
dm = DataModel(short_data=self.binary_data*4)
|
||||
self.assertRaises(ValidationError, dm.full_clean)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from datetime import date
|
||||
import warnings
|
||||
|
||||
from django import forms
|
||||
from django.core.exceptions import FieldError, ValidationError
|
||||
@@ -43,9 +44,12 @@ class ModelMultipleChoiceFieldTests(TestCase):
|
||||
f.clean([p.pk for p in Person.objects.all()[8:9]])
|
||||
self.assertTrue(self._validator_run)
|
||||
|
||||
|
||||
class TripleForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Triple
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class UniqueTogetherTests(TestCase):
|
||||
def test_multiple_field_unique_together(self):
|
||||
@@ -63,15 +67,18 @@ class UniqueTogetherTests(TestCase):
|
||||
form = TripleForm({'left': '1', 'middle': '3', 'right': '1'})
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
|
||||
class TripleFormWithCleanOverride(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Triple
|
||||
fields = '__all__'
|
||||
|
||||
def clean(self):
|
||||
if not self.cleaned_data['left'] == self.cleaned_data['right']:
|
||||
raise forms.ValidationError('Left and right should be equal')
|
||||
return self.cleaned_data
|
||||
|
||||
|
||||
class OverrideCleanTests(TestCase):
|
||||
def test_override_clean(self):
|
||||
"""
|
||||
@@ -84,6 +91,7 @@ class OverrideCleanTests(TestCase):
|
||||
# by form.full_clean().
|
||||
self.assertEqual(form.instance.left, 1)
|
||||
|
||||
|
||||
# Regression test for #12960.
|
||||
# Make sure the cleaned_data returned from ModelForm.clean() is applied to the
|
||||
# model instance.
|
||||
@@ -95,6 +103,8 @@ class PublicationForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Publication
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class ModelFormCleanTest(TestCase):
|
||||
def test_model_form_clean_applies_to_model(self):
|
||||
@@ -103,9 +113,12 @@ class ModelFormCleanTest(TestCase):
|
||||
publication = form.save()
|
||||
self.assertEqual(publication.title, 'TEST')
|
||||
|
||||
|
||||
class FPForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = FilePathModel
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class FilePathFieldTests(TestCase):
|
||||
def test_file_path_field_blank(self):
|
||||
@@ -133,7 +146,8 @@ class ManyToManyCallableInitialTests(TestCase):
|
||||
book3 = Publication.objects.create(title="Third Book", date_published=date(2009,1,1))
|
||||
|
||||
# Create a ModelForm, instantiate it, and check that the output is as expected
|
||||
ModelForm = modelform_factory(Article, formfield_callback=formfield_for_dbfield)
|
||||
ModelForm = modelform_factory(Article, fields="__all__",
|
||||
formfield_callback=formfield_for_dbfield)
|
||||
form = ModelForm()
|
||||
self.assertHTMLEqual(form.as_ul(), """<li><label for="id_headline">Headline:</label> <input id="id_headline" type="text" name="headline" maxlength="100" /></li>
|
||||
<li><label for="id_publications">Publications:</label> <select multiple="multiple" name="publications" id="id_publications">
|
||||
@@ -143,9 +157,12 @@ class ManyToManyCallableInitialTests(TestCase):
|
||||
</select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>"""
|
||||
% (book1.pk, book2.pk, book3.pk))
|
||||
|
||||
|
||||
class CFFForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = CustomFF
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class CustomFieldSaveTests(TestCase):
|
||||
def test_save(self):
|
||||
@@ -168,9 +185,12 @@ class ModelChoiceIteratorTests(TestCase):
|
||||
f = Form()
|
||||
self.assertEqual(len(f.fields["publications"].choices), 1)
|
||||
|
||||
|
||||
class RealPersonForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = RealPerson
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class CustomModelFormSaveMethod(TestCase):
|
||||
def test_string_message(self):
|
||||
@@ -230,9 +250,12 @@ class TestTicket11183(TestCase):
|
||||
self.assertTrue(field1 is not ModelChoiceForm.base_fields['person'])
|
||||
self.assertTrue(field1.widget.choices.field is field1)
|
||||
|
||||
|
||||
class HomepageForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Homepage
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class URLFieldTests(TestCase):
|
||||
def test_url_on_modelform(self):
|
||||
@@ -274,6 +297,7 @@ class FormFieldCallbackTests(TestCase):
|
||||
class Meta:
|
||||
model = Person
|
||||
widgets = {'name': widget}
|
||||
fields = "__all__"
|
||||
|
||||
Form = modelform_factory(Person, form=BaseForm)
|
||||
self.assertTrue(Form.base_fields['name'].widget is widget)
|
||||
@@ -285,11 +309,11 @@ class FormFieldCallbackTests(TestCase):
|
||||
widget = forms.Textarea()
|
||||
|
||||
# Without a widget should not set the widget to textarea
|
||||
Form = modelform_factory(Person)
|
||||
Form = modelform_factory(Person, fields="__all__")
|
||||
self.assertNotEqual(Form.base_fields['name'].widget.__class__, forms.Textarea)
|
||||
|
||||
# With a widget should not set the widget to textarea
|
||||
Form = modelform_factory(Person, widgets={'name':widget})
|
||||
Form = modelform_factory(Person, fields="__all__", widgets={'name':widget})
|
||||
self.assertEqual(Form.base_fields['name'].widget.__class__, forms.Textarea)
|
||||
|
||||
def test_custom_callback(self):
|
||||
@@ -307,6 +331,7 @@ class FormFieldCallbackTests(TestCase):
|
||||
class Meta:
|
||||
model = Person
|
||||
widgets = {'name': widget}
|
||||
fields = "__all__"
|
||||
|
||||
_ = modelform_factory(Person, form=BaseForm,
|
||||
formfield_callback=callback)
|
||||
@@ -317,7 +342,7 @@ class FormFieldCallbackTests(TestCase):
|
||||
|
||||
def test_bad_callback(self):
|
||||
# A bad callback provided by user still gives an error
|
||||
self.assertRaises(TypeError, modelform_factory, Person,
|
||||
self.assertRaises(TypeError, modelform_factory, Person, fields="__all__",
|
||||
formfield_callback='not a function or callable')
|
||||
|
||||
|
||||
@@ -362,6 +387,8 @@ class InvalidFieldAndFactory(TestCase):
|
||||
class DocumentForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Document
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class FileFieldTests(unittest.TestCase):
|
||||
def test_clean_false(self):
|
||||
@@ -425,6 +452,7 @@ class FileFieldTests(unittest.TestCase):
|
||||
self.assertTrue('something.txt' in rendered)
|
||||
self.assertTrue('myfile-clear' in rendered)
|
||||
|
||||
|
||||
class EditionForm(forms.ModelForm):
|
||||
author = forms.ModelChoiceField(queryset=Person.objects.all())
|
||||
publication = forms.ModelChoiceField(queryset=Publication.objects.all())
|
||||
@@ -433,6 +461,8 @@ class EditionForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Edition
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class UniqueErrorsTests(TestCase):
|
||||
def setUp(self):
|
||||
@@ -473,7 +503,7 @@ class EmptyFieldsTestCase(TestCase):
|
||||
|
||||
def test_empty_fields_to_construct_instance(self):
|
||||
"No fields should be set on a model instance if construct_instance receives fields=()"
|
||||
form = modelform_factory(Person)({'name': 'John Doe'})
|
||||
form = modelform_factory(Person, fields="__all__")({'name': 'John Doe'})
|
||||
self.assertTrue(form.is_valid())
|
||||
instance = construct_instance(form, Person(), fields=())
|
||||
self.assertEqual(instance.name, '')
|
||||
@@ -485,10 +515,25 @@ class CustomMetaclass(ModelFormMetaclass):
|
||||
new.base_fields = {}
|
||||
return new
|
||||
|
||||
|
||||
class CustomMetaclassForm(six.with_metaclass(CustomMetaclass, forms.ModelForm)):
|
||||
pass
|
||||
|
||||
|
||||
class CustomMetaclassTestCase(TestCase):
|
||||
def test_modelform_factory_metaclass(self):
|
||||
new_cls = modelform_factory(Person, form=CustomMetaclassForm)
|
||||
new_cls = modelform_factory(Person, fields="__all__", form=CustomMetaclassForm)
|
||||
self.assertEqual(new_cls.base_fields, {})
|
||||
|
||||
|
||||
class TestTicket19733(TestCase):
|
||||
def test_modelform_factory_without_fields(self):
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always", PendingDeprecationWarning)
|
||||
# This should become an error once deprecation cycle is complete.
|
||||
form = modelform_factory(Person)
|
||||
self.assertEqual(w[0].category, PendingDeprecationWarning)
|
||||
|
||||
def test_modelform_factory_with_all_fields(self):
|
||||
form = modelform_factory(Person, fields="__all__")
|
||||
self.assertEqual(list(form.base_fields), ["name"])
|
||||
|
||||
@@ -21,7 +21,7 @@ from .models import (Author, BetterAuthor, Book, BookWithCustomPK,
|
||||
|
||||
class DeletionTests(TestCase):
|
||||
def test_deletion(self):
|
||||
PoetFormSet = modelformset_factory(Poet, can_delete=True)
|
||||
PoetFormSet = modelformset_factory(Poet, fields="__all__", can_delete=True)
|
||||
poet = Poet.objects.create(name='test')
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '1',
|
||||
@@ -41,7 +41,7 @@ class DeletionTests(TestCase):
|
||||
Make sure that an add form that is filled out, but marked for deletion
|
||||
doesn't cause validation errors.
|
||||
"""
|
||||
PoetFormSet = modelformset_factory(Poet, can_delete=True)
|
||||
PoetFormSet = modelformset_factory(Poet, fields="__all__", can_delete=True)
|
||||
poet = Poet.objects.create(name='test')
|
||||
# One existing untouched and two new unvalid forms
|
||||
data = {
|
||||
@@ -75,7 +75,7 @@ class DeletionTests(TestCase):
|
||||
Make sure that a change form that is filled out, but marked for deletion
|
||||
doesn't cause validation errors.
|
||||
"""
|
||||
PoetFormSet = modelformset_factory(Poet, can_delete=True)
|
||||
PoetFormSet = modelformset_factory(Poet, fields="__all__", can_delete=True)
|
||||
poet = Poet.objects.create(name='test')
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '1',
|
||||
@@ -100,7 +100,7 @@ class DeletionTests(TestCase):
|
||||
class ModelFormsetTest(TestCase):
|
||||
def test_simple_save(self):
|
||||
qs = Author.objects.all()
|
||||
AuthorFormSet = modelformset_factory(Author, extra=3)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", extra=3)
|
||||
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertEqual(len(formset.forms), 3)
|
||||
@@ -138,7 +138,7 @@ class ModelFormsetTest(TestCase):
|
||||
# we'll use it to display them in alphabetical order by name.
|
||||
|
||||
qs = Author.objects.order_by('name')
|
||||
AuthorFormSet = modelformset_factory(Author, extra=1, can_delete=False)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", extra=1, can_delete=False)
|
||||
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertEqual(len(formset.forms), 3)
|
||||
@@ -176,7 +176,7 @@ class ModelFormsetTest(TestCase):
|
||||
# marked for deletion, make sure we don't save that form.
|
||||
|
||||
qs = Author.objects.order_by('name')
|
||||
AuthorFormSet = modelformset_factory(Author, extra=1, can_delete=True)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", extra=1, can_delete=True)
|
||||
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertEqual(len(formset.forms), 4)
|
||||
@@ -256,7 +256,7 @@ class ModelFormsetTest(TestCase):
|
||||
|
||||
author4 = Author.objects.create(name='John Steinbeck')
|
||||
|
||||
AuthorMeetingFormSet = modelformset_factory(AuthorMeeting, extra=1, can_delete=True)
|
||||
AuthorMeetingFormSet = modelformset_factory(AuthorMeeting, fields="__all__", extra=1, can_delete=True)
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '2', # the number of forms rendered
|
||||
'form-INITIAL_FORMS': '1', # the number of forms with initial data
|
||||
@@ -294,22 +294,22 @@ class ModelFormsetTest(TestCase):
|
||||
|
||||
qs = Author.objects.order_by('name')
|
||||
|
||||
AuthorFormSet = modelformset_factory(Author, max_num=None, extra=3)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", max_num=None, extra=3)
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertEqual(len(formset.forms), 6)
|
||||
self.assertEqual(len(formset.extra_forms), 3)
|
||||
|
||||
AuthorFormSet = modelformset_factory(Author, max_num=4, extra=3)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", max_num=4, extra=3)
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertEqual(len(formset.forms), 4)
|
||||
self.assertEqual(len(formset.extra_forms), 1)
|
||||
|
||||
AuthorFormSet = modelformset_factory(Author, max_num=0, extra=3)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", max_num=0, extra=3)
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertEqual(len(formset.forms), 3)
|
||||
self.assertEqual(len(formset.extra_forms), 0)
|
||||
|
||||
AuthorFormSet = modelformset_factory(Author, max_num=None)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", max_num=None)
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertQuerysetEqual(formset.get_queryset(), [
|
||||
'<Author: Charles Baudelaire>',
|
||||
@@ -317,7 +317,7 @@ class ModelFormsetTest(TestCase):
|
||||
'<Author: Walt Whitman>',
|
||||
])
|
||||
|
||||
AuthorFormSet = modelformset_factory(Author, max_num=0)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", max_num=0)
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertQuerysetEqual(formset.get_queryset(), [
|
||||
'<Author: Charles Baudelaire>',
|
||||
@@ -325,7 +325,7 @@ class ModelFormsetTest(TestCase):
|
||||
'<Author: Walt Whitman>',
|
||||
])
|
||||
|
||||
AuthorFormSet = modelformset_factory(Author, max_num=4)
|
||||
AuthorFormSet = modelformset_factory(Author, fields="__all__", max_num=4)
|
||||
formset = AuthorFormSet(queryset=qs)
|
||||
self.assertQuerysetEqual(formset.get_queryset(), [
|
||||
'<Author: Charles Baudelaire>',
|
||||
@@ -343,7 +343,7 @@ class ModelFormsetTest(TestCase):
|
||||
author.save()
|
||||
return author
|
||||
|
||||
PoetFormSet = modelformset_factory(Poet, form=PoetForm)
|
||||
PoetFormSet = modelformset_factory(Poet, fields="__all__", form=PoetForm)
|
||||
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '3', # the number of forms rendered
|
||||
@@ -387,7 +387,7 @@ class ModelFormsetTest(TestCase):
|
||||
self.assertFalse("subtitle" in formset.forms[0].fields)
|
||||
|
||||
def test_model_inheritance(self):
|
||||
BetterAuthorFormSet = modelformset_factory(BetterAuthor)
|
||||
BetterAuthorFormSet = modelformset_factory(BetterAuthor, fields="__all__")
|
||||
formset = BetterAuthorFormSet()
|
||||
self.assertEqual(len(formset.forms), 1)
|
||||
self.assertHTMLEqual(formset.forms[0].as_p(),
|
||||
@@ -440,7 +440,7 @@ class ModelFormsetTest(TestCase):
|
||||
# We can also create a formset that is tied to a parent model. This is
|
||||
# how the admin system's edit inline functionality works.
|
||||
|
||||
AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=3)
|
||||
AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=3, fields="__all__")
|
||||
author = Author.objects.create(name='Charles Baudelaire')
|
||||
|
||||
formset = AuthorBooksFormSet(instance=author)
|
||||
@@ -474,7 +474,7 @@ class ModelFormsetTest(TestCase):
|
||||
# another one. This time though, an edit form will be available for
|
||||
# every existing book.
|
||||
|
||||
AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2)
|
||||
AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2, fields="__all__")
|
||||
author = Author.objects.get(name='Charles Baudelaire')
|
||||
|
||||
formset = AuthorBooksFormSet(instance=author)
|
||||
@@ -514,7 +514,7 @@ class ModelFormsetTest(TestCase):
|
||||
def test_inline_formsets_save_as_new(self):
|
||||
# The save_as_new parameter lets you re-associate the data to a new
|
||||
# instance. This is used in the admin for save_as functionality.
|
||||
AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2)
|
||||
AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2, fields="__all__")
|
||||
author = Author.objects.create(name='Charles Baudelaire')
|
||||
|
||||
data = {
|
||||
@@ -553,7 +553,7 @@ class ModelFormsetTest(TestCase):
|
||||
# primary key that is not the fk to the parent object.
|
||||
self.maxDiff = 1024
|
||||
|
||||
AuthorBooksFormSet2 = inlineformset_factory(Author, BookWithCustomPK, can_delete=False, extra=1)
|
||||
AuthorBooksFormSet2 = inlineformset_factory(Author, BookWithCustomPK, can_delete=False, extra=1, fields="__all__")
|
||||
author = Author.objects.create(pk=1, name='Charles Baudelaire')
|
||||
|
||||
formset = AuthorBooksFormSet2(instance=author)
|
||||
@@ -585,7 +585,7 @@ class ModelFormsetTest(TestCase):
|
||||
# Test inline formsets where the inline-edited object uses multi-table
|
||||
# inheritance, thus has a non AutoField yet auto-created primary key.
|
||||
|
||||
AuthorBooksFormSet3 = inlineformset_factory(Author, AlternateBook, can_delete=False, extra=1)
|
||||
AuthorBooksFormSet3 = inlineformset_factory(Author, AlternateBook, can_delete=False, extra=1, fields="__all__")
|
||||
author = Author.objects.create(pk=1, name='Charles Baudelaire')
|
||||
|
||||
formset = AuthorBooksFormSet3(instance=author)
|
||||
@@ -616,7 +616,7 @@ class ModelFormsetTest(TestCase):
|
||||
# Test inline formsets where the inline-edited object has a
|
||||
# unique_together constraint with a nullable member
|
||||
|
||||
AuthorBooksFormSet4 = inlineformset_factory(Author, BookWithOptionalAltEditor, can_delete=False, extra=2)
|
||||
AuthorBooksFormSet4 = inlineformset_factory(Author, BookWithOptionalAltEditor, can_delete=False, extra=2, fields="__all__")
|
||||
author = Author.objects.create(pk=1, name='Charles Baudelaire')
|
||||
|
||||
data = {
|
||||
@@ -640,7 +640,7 @@ class ModelFormsetTest(TestCase):
|
||||
self.assertEqual(book2.title, 'Les Fleurs du Mal')
|
||||
|
||||
def test_inline_formsets_with_custom_save_method(self):
|
||||
AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2)
|
||||
AuthorBooksFormSet = inlineformset_factory(Author, Book, can_delete=False, extra=2, fields="__all__")
|
||||
author = Author.objects.create(pk=1, name='Charles Baudelaire')
|
||||
book1 = Book.objects.create(pk=1, author=author, title='Les Paradis Artificiels')
|
||||
book2 = Book.objects.create(pk=2, author=author, title='Les Fleurs du Mal')
|
||||
@@ -655,7 +655,7 @@ class ModelFormsetTest(TestCase):
|
||||
poem.save()
|
||||
return poem
|
||||
|
||||
PoemFormSet = inlineformset_factory(Poet, Poem, form=PoemForm)
|
||||
PoemFormSet = inlineformset_factory(Poet, Poem, form=PoemForm, fields="__all__")
|
||||
|
||||
data = {
|
||||
'poem_set-TOTAL_FORMS': '3', # the number of forms rendered
|
||||
@@ -732,7 +732,7 @@ class ModelFormsetTest(TestCase):
|
||||
def test_custom_pk(self):
|
||||
# We need to ensure that it is displayed
|
||||
|
||||
CustomPrimaryKeyFormSet = modelformset_factory(CustomPrimaryKey)
|
||||
CustomPrimaryKeyFormSet = modelformset_factory(CustomPrimaryKey, fields="__all__")
|
||||
formset = CustomPrimaryKeyFormSet()
|
||||
self.assertEqual(len(formset.forms), 1)
|
||||
self.assertHTMLEqual(formset.forms[0].as_p(),
|
||||
@@ -743,7 +743,7 @@ class ModelFormsetTest(TestCase):
|
||||
|
||||
place = Place.objects.create(pk=1, name='Giordanos', city='Chicago')
|
||||
|
||||
FormSet = inlineformset_factory(Place, Owner, extra=2, can_delete=False)
|
||||
FormSet = inlineformset_factory(Place, Owner, extra=2, can_delete=False, fields="__all__")
|
||||
formset = FormSet(instance=place)
|
||||
self.assertEqual(len(formset.forms), 2)
|
||||
self.assertHTMLEqual(formset.forms[0].as_p(),
|
||||
@@ -799,7 +799,7 @@ class ModelFormsetTest(TestCase):
|
||||
|
||||
# Ensure a custom primary key that is a ForeignKey or OneToOneField get rendered for the user to choose.
|
||||
|
||||
FormSet = modelformset_factory(OwnerProfile)
|
||||
FormSet = modelformset_factory(OwnerProfile, fields="__all__")
|
||||
formset = FormSet()
|
||||
self.assertHTMLEqual(formset.forms[0].as_p(),
|
||||
'<p><label for="id_form-0-owner">Owner:</label> <select name="form-0-owner" id="id_form-0-owner">\n'
|
||||
@@ -811,7 +811,7 @@ class ModelFormsetTest(TestCase):
|
||||
% (owner1.auto_id, owner2.auto_id))
|
||||
|
||||
owner1 = Owner.objects.get(name='Joe Perry')
|
||||
FormSet = inlineformset_factory(Owner, OwnerProfile, max_num=1, can_delete=False)
|
||||
FormSet = inlineformset_factory(Owner, OwnerProfile, max_num=1, can_delete=False, fields="__all__")
|
||||
self.assertEqual(FormSet.max_num, 1)
|
||||
|
||||
formset = FormSet(instance=owner1)
|
||||
@@ -861,7 +861,7 @@ class ModelFormsetTest(TestCase):
|
||||
|
||||
place = Place.objects.create(pk=1, name='Giordanos', city='Chicago')
|
||||
|
||||
FormSet = inlineformset_factory(Place, Location, can_delete=False)
|
||||
FormSet = inlineformset_factory(Place, Location, can_delete=False, fields="__all__")
|
||||
self.assertEqual(FormSet.max_num, 1)
|
||||
|
||||
formset = FormSet(instance=place)
|
||||
@@ -875,7 +875,7 @@ class ModelFormsetTest(TestCase):
|
||||
self.assertEqual(type(_get_foreign_key(MexicanRestaurant, Owner)), models.ForeignKey)
|
||||
|
||||
def test_unique_validation(self):
|
||||
FormSet = modelformset_factory(Product, extra=1)
|
||||
FormSet = modelformset_factory(Product, fields="__all__", extra=1)
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '1',
|
||||
'form-INITIAL_FORMS': '0',
|
||||
@@ -915,19 +915,19 @@ class ModelFormsetTest(TestCase):
|
||||
'form-1-quantity': '2',
|
||||
}
|
||||
|
||||
FormSet = modelformset_factory(Price, extra=1, max_num=1, validate_max=True)
|
||||
FormSet = modelformset_factory(Price, fields="__all__", extra=1, max_num=1, validate_max=True)
|
||||
formset = FormSet(data)
|
||||
self.assertFalse(formset.is_valid())
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit 1 or fewer forms.'])
|
||||
|
||||
# Now test the same thing without the validate_max flag to ensure
|
||||
# default behavior is unchanged
|
||||
FormSet = modelformset_factory(Price, extra=1, max_num=1)
|
||||
FormSet = modelformset_factory(Price, fields="__all__", extra=1, max_num=1)
|
||||
formset = FormSet(data)
|
||||
self.assertTrue(formset.is_valid())
|
||||
|
||||
def test_unique_together_validation(self):
|
||||
FormSet = modelformset_factory(Price, extra=1)
|
||||
FormSet = modelformset_factory(Price, fields="__all__", extra=1)
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '1',
|
||||
'form-INITIAL_FORMS': '0',
|
||||
@@ -958,7 +958,7 @@ class ModelFormsetTest(TestCase):
|
||||
# Also see bug #8882.
|
||||
|
||||
repository = Repository.objects.create(name='Test Repo')
|
||||
FormSet = inlineformset_factory(Repository, Revision, extra=1)
|
||||
FormSet = inlineformset_factory(Repository, Revision, extra=1, fields="__all__")
|
||||
data = {
|
||||
'revision_set-TOTAL_FORMS': '1',
|
||||
'revision_set-INITIAL_FORMS': '0',
|
||||
@@ -1007,7 +1007,7 @@ class ModelFormsetTest(TestCase):
|
||||
# Use of callable defaults (see bug #7975).
|
||||
|
||||
person = Person.objects.create(name='Ringo')
|
||||
FormSet = inlineformset_factory(Person, Membership, can_delete=False, extra=1)
|
||||
FormSet = inlineformset_factory(Person, Membership, can_delete=False, extra=1, fields="__all__")
|
||||
formset = FormSet(instance=person)
|
||||
|
||||
# Django will render a hidden field for model fields that have a callable
|
||||
@@ -1057,11 +1057,12 @@ class ModelFormsetTest(TestCase):
|
||||
date_joined = forms.SplitDateTimeField(initial=now)
|
||||
class Meta:
|
||||
model = Membership
|
||||
fields = "__all__"
|
||||
def __init__(self, **kwargs):
|
||||
super(MembershipForm, self).__init__(**kwargs)
|
||||
self.fields['date_joined'].widget = forms.SplitDateTimeWidget()
|
||||
|
||||
FormSet = inlineformset_factory(Person, Membership, form=MembershipForm, can_delete=False, extra=1)
|
||||
FormSet = inlineformset_factory(Person, Membership, form=MembershipForm, can_delete=False, extra=1, fields="__all__")
|
||||
data = {
|
||||
'membership_set-TOTAL_FORMS': '1',
|
||||
'membership_set-INITIAL_FORMS': '0',
|
||||
@@ -1081,7 +1082,7 @@ class ModelFormsetTest(TestCase):
|
||||
Player(name="Timmy").save()
|
||||
Player(name="Bobby", team=team).save()
|
||||
|
||||
PlayerInlineFormSet = inlineformset_factory(Team, Player)
|
||||
PlayerInlineFormSet = inlineformset_factory(Team, Player, fields="__all__")
|
||||
formset = PlayerInlineFormSet()
|
||||
self.assertQuerysetEqual(formset.get_queryset(), [])
|
||||
|
||||
@@ -1101,7 +1102,7 @@ class ModelFormsetTest(TestCase):
|
||||
def test_model_formset_with_initial_model_instance(self):
|
||||
# has_changed should compare model instance and primary key
|
||||
# see #18898
|
||||
FormSet = modelformset_factory(Poem)
|
||||
FormSet = modelformset_factory(Poem, fields='__all__')
|
||||
john_milton = Poet(name="John Milton")
|
||||
john_milton.save()
|
||||
data = {
|
||||
@@ -1117,7 +1118,7 @@ class ModelFormsetTest(TestCase):
|
||||
def test_model_formset_with_initial_queryset(self):
|
||||
# has_changed should work with queryset and list of pk's
|
||||
# see #18898
|
||||
FormSet = modelformset_factory(AuthorMeeting)
|
||||
FormSet = modelformset_factory(AuthorMeeting, fields='__all__')
|
||||
author = Author.objects.create(pk=1, name='Charles Baudelaire')
|
||||
data = {
|
||||
'form-TOTAL_FORMS': 1,
|
||||
@@ -1131,7 +1132,7 @@ class ModelFormsetTest(TestCase):
|
||||
self.assertFalse(formset.extra_forms[0].has_changed())
|
||||
|
||||
def test_prevent_duplicates_from_with_the_same_formset(self):
|
||||
FormSet = modelformset_factory(Product, extra=2)
|
||||
FormSet = modelformset_factory(Product, fields="__all__", extra=2)
|
||||
data = {
|
||||
'form-TOTAL_FORMS': 2,
|
||||
'form-INITIAL_FORMS': 0,
|
||||
@@ -1144,7 +1145,7 @@ class ModelFormsetTest(TestCase):
|
||||
self.assertEqual(formset._non_form_errors,
|
||||
['Please correct the duplicate data for slug.'])
|
||||
|
||||
FormSet = modelformset_factory(Price, extra=2)
|
||||
FormSet = modelformset_factory(Price, fields="__all__", extra=2)
|
||||
data = {
|
||||
'form-TOTAL_FORMS': 2,
|
||||
'form-INITIAL_FORMS': 0,
|
||||
@@ -1172,7 +1173,7 @@ class ModelFormsetTest(TestCase):
|
||||
formset = FormSet(data)
|
||||
self.assertTrue(formset.is_valid())
|
||||
|
||||
FormSet = inlineformset_factory(Author, Book, extra=0)
|
||||
FormSet = inlineformset_factory(Author, Book, extra=0, fields="__all__")
|
||||
author = Author.objects.create(pk=1, name='Charles Baudelaire')
|
||||
book1 = Book.objects.create(pk=1, author=author, title='Les Paradis Artificiels')
|
||||
book2 = Book.objects.create(pk=2, author=author, title='Les Fleurs du Mal')
|
||||
@@ -1199,7 +1200,7 @@ class ModelFormsetTest(TestCase):
|
||||
self.assertEqual(formset.errors,
|
||||
[{}, {'__all__': ['Please correct the duplicate values below.']}])
|
||||
|
||||
FormSet = modelformset_factory(Post, extra=2)
|
||||
FormSet = modelformset_factory(Post, fields="__all__", extra=2)
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '2',
|
||||
'form-INITIAL_FORMS': '0',
|
||||
@@ -1265,7 +1266,7 @@ class TestModelFormsetWidgets(TestCase):
|
||||
widgets = {
|
||||
'name': forms.TextInput(attrs={'class': 'poet'})
|
||||
}
|
||||
PoetFormSet = modelformset_factory(Poet, widgets=widgets)
|
||||
PoetFormSet = modelformset_factory(Poet, fields="__all__", widgets=widgets)
|
||||
form = PoetFormSet.form()
|
||||
self.assertHTMLEqual(
|
||||
"%s" % form['name'],
|
||||
@@ -1276,7 +1277,7 @@ class TestModelFormsetWidgets(TestCase):
|
||||
widgets = {
|
||||
'title': forms.TextInput(attrs={'class': 'book'})
|
||||
}
|
||||
BookFormSet = inlineformset_factory(Author, Book, widgets=widgets)
|
||||
BookFormSet = inlineformset_factory(Author, Book, widgets=widgets, fields="__all__")
|
||||
form = BookFormSet.form()
|
||||
self.assertHTMLEqual(
|
||||
"%s" % form['title'],
|
||||
|
||||
@@ -13,8 +13,8 @@ from .models import User, UserSite, Restaurant, Manager, Network, Host
|
||||
class InlineFormsetTests(TestCase):
|
||||
def test_formset_over_to_field(self):
|
||||
"A formset over a ForeignKey with a to_field can be saved. Regression for #10243"
|
||||
Form = modelform_factory(User)
|
||||
FormSet = inlineformset_factory(User, UserSite)
|
||||
Form = modelform_factory(User, fields="__all__")
|
||||
FormSet = inlineformset_factory(User, UserSite, fields="__all__")
|
||||
|
||||
# Instantiate the Form and FormSet to prove
|
||||
# you can create a form with no data
|
||||
@@ -89,8 +89,8 @@ class InlineFormsetTests(TestCase):
|
||||
|
||||
def test_formset_over_inherited_model(self):
|
||||
"A formset over a ForeignKey with a to_field can be saved. Regression for #11120"
|
||||
Form = modelform_factory(Restaurant)
|
||||
FormSet = inlineformset_factory(Restaurant, Manager)
|
||||
Form = modelform_factory(Restaurant, fields="__all__")
|
||||
FormSet = inlineformset_factory(Restaurant, Manager, fields="__all__")
|
||||
|
||||
# Instantiate the Form and FormSet to prove
|
||||
# you can create a form with no data
|
||||
@@ -156,8 +156,8 @@ class InlineFormsetTests(TestCase):
|
||||
|
||||
def test_formset_with_none_instance(self):
|
||||
"A formset with instance=None can be created. Regression for #11872"
|
||||
Form = modelform_factory(User)
|
||||
FormSet = inlineformset_factory(User, UserSite)
|
||||
Form = modelform_factory(User, fields="__all__")
|
||||
FormSet = inlineformset_factory(User, UserSite, fields="__all__")
|
||||
|
||||
# Instantiate the Form and FormSet to prove
|
||||
# you can create a formset with an instance of None
|
||||
@@ -182,7 +182,7 @@ class InlineFormsetTests(TestCase):
|
||||
efnet = Network.objects.create(name="EFNet")
|
||||
host1 = Host.objects.create(hostname="irc.he.net", network=efnet)
|
||||
|
||||
HostFormSet = inlineformset_factory(Network, Host)
|
||||
HostFormSet = inlineformset_factory(Network, Host, fields="__all__")
|
||||
|
||||
# Add a new host, modify previous host, and save-as-new
|
||||
data = {
|
||||
@@ -208,7 +208,7 @@ class InlineFormsetTests(TestCase):
|
||||
def test_initial_data(self):
|
||||
user = User.objects.create(username="bibi", serial=1)
|
||||
UserSite.objects.create(user=user, data=7)
|
||||
FormSet = inlineformset_factory(User, UserSite, extra=2)
|
||||
FormSet = inlineformset_factory(User, UserSite, extra=2, fields="__all__")
|
||||
|
||||
formset = FormSet(instance=user, initial=[{'data': 41}, {'data': 42}])
|
||||
self.assertEqual(formset.forms[0].initial['data'], 7)
|
||||
@@ -221,7 +221,7 @@ class FormsetTests(TestCase):
|
||||
'''
|
||||
Test the type of Formset and Form error attributes
|
||||
'''
|
||||
Formset = modelformset_factory(User)
|
||||
Formset = modelformset_factory(User, fields="__all__")
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '2',
|
||||
'form-INITIAL_FORMS': '0',
|
||||
@@ -244,14 +244,14 @@ class FormsetTests(TestCase):
|
||||
|
||||
def test_initial_data(self):
|
||||
User.objects.create(username="bibi", serial=1)
|
||||
Formset = modelformset_factory(User, extra=2)
|
||||
Formset = modelformset_factory(User, fields="__all__", extra=2)
|
||||
formset = Formset(initial=[{'username': 'apollo11'}, {'username': 'apollo12'}])
|
||||
self.assertEqual(formset.forms[0].initial['username'], "bibi")
|
||||
self.assertEqual(formset.extra_forms[0].initial['username'], "apollo11")
|
||||
self.assertTrue('value="apollo12"' in formset.extra_forms[1].as_p())
|
||||
|
||||
def test_extraneous_query_is_not_run(self):
|
||||
Formset = modelformset_factory(Network)
|
||||
Formset = modelformset_factory(Network, fields="__all__")
|
||||
data = {'test-TOTAL_FORMS': '1',
|
||||
'test-INITIAL_FORMS': '0',
|
||||
'test-MAX_NUM_FORMS': '',
|
||||
@@ -268,6 +268,7 @@ class CustomWidget(forms.widgets.TextInput):
|
||||
class UserSiteForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = UserSite
|
||||
fields = "__all__"
|
||||
widgets = {
|
||||
'id': CustomWidget,
|
||||
'data': CustomWidget,
|
||||
@@ -292,7 +293,7 @@ class FormfieldCallbackTests(TestCase):
|
||||
"""
|
||||
|
||||
def test_inlineformset_factory_default(self):
|
||||
Formset = inlineformset_factory(User, UserSite, form=UserSiteForm)
|
||||
Formset = inlineformset_factory(User, UserSite, form=UserSiteForm, fields="__all__")
|
||||
form = Formset().forms[0]
|
||||
self.assertTrue(isinstance(form['id'].field.widget, CustomWidget))
|
||||
self.assertTrue(isinstance(form['data'].field.widget, CustomWidget))
|
||||
@@ -315,7 +316,7 @@ class FormfieldCallbackTests(TestCase):
|
||||
def test_inlineformset_custom_callback(self):
|
||||
callback = Callback()
|
||||
inlineformset_factory(User, UserSite, form=UserSiteForm,
|
||||
formfield_callback=callback)
|
||||
formfield_callback=callback, fields="__all__")
|
||||
self.assertCallbackCalled(callback)
|
||||
|
||||
def test_modelformset_custom_callback(self):
|
||||
@@ -353,6 +354,7 @@ class FormfieldShouldDeleteFormTests(TestCase):
|
||||
""" A model form with a 'should_delete' method """
|
||||
class Meta:
|
||||
model = User
|
||||
fields = "__all__"
|
||||
|
||||
def should_delete(self):
|
||||
""" delete form if odd PK """
|
||||
|
||||
@@ -418,6 +418,8 @@ class ModelInheritanceTest(TestCase):
|
||||
class ProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = '__all__'
|
||||
|
||||
User.objects.create(username="user_only")
|
||||
p = Profile.objects.create(username="user_with_profile")
|
||||
form = ProfileForm({'username': "user_with_profile", 'extra': "hello"},
|
||||
|
||||
@@ -2,12 +2,14 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import datetime
|
||||
from operator import attrgetter
|
||||
import sys
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
from django.utils import six
|
||||
from django.utils import tzinfo
|
||||
from django.db import router
|
||||
from django.utils import unittest
|
||||
from django.db import connection, router
|
||||
from django.db.models.sql import InsertQuery
|
||||
|
||||
from .models import (Worker, Article, Party, Event, Department,
|
||||
@@ -131,6 +133,11 @@ class ModelTests(TestCase):
|
||||
attrgetter("when")
|
||||
)
|
||||
|
||||
if (3,) <= sys.version_info < (3, 3) and connection.vendor == 'mysql':
|
||||
# In Python < 3.3, datetime.strftime raises an exception for years
|
||||
# below 1000, and existing MySQL DB-API drivers hit this problem.
|
||||
test_date_lookup = unittest.expectedFailure(test_date_lookup)
|
||||
|
||||
def test_date_filter_null(self):
|
||||
# Date filtering was failing with NULL date values in SQLite
|
||||
# (regression test for #3501, amongst other things).
|
||||
|
||||
@@ -229,9 +229,6 @@ class ModelAdminTests(TestCase):
|
||||
class AdminBandForm(forms.ModelForm):
|
||||
delete = forms.BooleanField()
|
||||
|
||||
class Meta:
|
||||
model = Band
|
||||
|
||||
class BandAdmin(ModelAdmin):
|
||||
form = AdminBandForm
|
||||
|
||||
@@ -319,8 +316,7 @@ class ModelAdminTests(TestCase):
|
||||
'</select>' % (band2.id, self.band.id))
|
||||
|
||||
class AdminConcertForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Concert
|
||||
pass
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AdminConcertForm, self).__init__(*args, **kwargs)
|
||||
@@ -616,17 +612,6 @@ class ValidationTests(unittest.TestCase):
|
||||
ValidationTestModel,
|
||||
)
|
||||
|
||||
class ValidationTestModelAdmin(ModelAdmin):
|
||||
fieldsets = (("General", {"fields": ("non_existent_field",)}),)
|
||||
|
||||
six.assertRaisesRegex(self,
|
||||
ImproperlyConfigured,
|
||||
"'ValidationTestModelAdmin.fieldsets\[0\]\[1\]\['fields'\]' refers to field 'non_existent_field' that is missing from the form.",
|
||||
validate,
|
||||
ValidationTestModelAdmin,
|
||||
ValidationTestModel,
|
||||
)
|
||||
|
||||
class ValidationTestModelAdmin(ModelAdmin):
|
||||
fieldsets = (("General", {"fields": ("name",)}),)
|
||||
|
||||
@@ -684,22 +669,6 @@ class ValidationTests(unittest.TestCase):
|
||||
|
||||
def test_fieldsets_with_custom_form_validation(self):
|
||||
|
||||
class BandAdmin(ModelAdmin):
|
||||
|
||||
fieldsets = (
|
||||
('Band', {
|
||||
'fields': ('non_existent_field',)
|
||||
}),
|
||||
)
|
||||
|
||||
six.assertRaisesRegex(self,
|
||||
ImproperlyConfigured,
|
||||
"'BandAdmin.fieldsets\[0\]\[1\]\['fields'\]' refers to field 'non_existent_field' that is missing from the form.",
|
||||
validate,
|
||||
BandAdmin,
|
||||
Band,
|
||||
)
|
||||
|
||||
class BandAdmin(ModelAdmin):
|
||||
fieldsets = (
|
||||
('Band', {
|
||||
@@ -709,33 +678,9 @@ class ValidationTests(unittest.TestCase):
|
||||
|
||||
validate(BandAdmin, Band)
|
||||
|
||||
class AdminBandForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Band
|
||||
|
||||
class BandAdmin(ModelAdmin):
|
||||
form = AdminBandForm
|
||||
|
||||
fieldsets = (
|
||||
('Band', {
|
||||
'fields': ('non_existent_field',)
|
||||
}),
|
||||
)
|
||||
|
||||
six.assertRaisesRegex(self,
|
||||
ImproperlyConfigured,
|
||||
"'BandAdmin.fieldsets\[0]\[1\]\['fields'\]' refers to field 'non_existent_field' that is missing from the form.",
|
||||
validate,
|
||||
BandAdmin,
|
||||
Band,
|
||||
)
|
||||
|
||||
class AdminBandForm(forms.ModelForm):
|
||||
delete = forms.BooleanField()
|
||||
|
||||
class Meta:
|
||||
model = Band
|
||||
|
||||
class BandAdmin(ModelAdmin):
|
||||
form = AdminBandForm
|
||||
|
||||
@@ -1371,21 +1316,6 @@ class ValidationTests(unittest.TestCase):
|
||||
ValidationTestModel,
|
||||
)
|
||||
|
||||
class ValidationTestInline(TabularInline):
|
||||
model = ValidationTestInlineModel
|
||||
fields = ("non_existent_field",)
|
||||
|
||||
class ValidationTestModelAdmin(ModelAdmin):
|
||||
inlines = [ValidationTestInline]
|
||||
|
||||
six.assertRaisesRegex(self,
|
||||
ImproperlyConfigured,
|
||||
"'ValidationTestInline.fields' refers to field 'non_existent_field' that is missing from the form.",
|
||||
validate,
|
||||
ValidationTestModelAdmin,
|
||||
ValidationTestModel,
|
||||
)
|
||||
|
||||
def test_fk_name_validation(self):
|
||||
|
||||
class ValidationTestInline(TabularInline):
|
||||
|
||||
@@ -26,7 +26,7 @@ from django.test import TestCase
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.functional import curry
|
||||
from django.utils.unittest import skipUnless
|
||||
from django.utils.unittest import expectedFailure, skipUnless
|
||||
|
||||
from .models import (BinaryData, BooleanData, CharData, DateData, DateTimeData, EmailData,
|
||||
FileData, FilePathData, DecimalData, FloatData, IntegerData, IPAddressData,
|
||||
@@ -459,6 +459,11 @@ def serializerTest(format, self):
|
||||
for klass, count in instance_count.items():
|
||||
self.assertEqual(count, klass.objects.count())
|
||||
|
||||
if connection.vendor == 'mysql' and six.PY3:
|
||||
# Existing MySQL DB-API drivers fail on binary data.
|
||||
serializerTest = expectedFailure(serializerTest)
|
||||
|
||||
|
||||
def naturalKeySerializerTest(format, self):
|
||||
# Create all the objects defined in the test data
|
||||
objects = []
|
||||
|
||||
1
tests/staticfiles_tests/project/faulty/faulty.css
Normal file
1
tests/staticfiles_tests/project/faulty/faulty.css
Normal file
@@ -0,0 +1 @@
|
||||
@import url("missing.css");
|
||||
@@ -244,7 +244,7 @@ class TestCollection(CollectionTestCase, TestDefaults):
|
||||
|
||||
class TestCollectionClear(CollectionTestCase):
|
||||
"""
|
||||
Test the ``--clear`` option of the ``collectstatic`` managemenet command.
|
||||
Test the ``--clear`` option of the ``collectstatic`` management command.
|
||||
"""
|
||||
def run_collectstatic(self, **kwargs):
|
||||
clear_filepath = os.path.join(settings.STATIC_ROOT, 'cleared.txt')
|
||||
@@ -550,6 +550,21 @@ class TestCollectionCachedStorage(BaseCollectionTestCase,
|
||||
self.assertNotIn(b"cached/other.css", content)
|
||||
self.assertIn(b"other.d41d8cd98f00.css", content)
|
||||
|
||||
@override_settings(
|
||||
STATICFILES_DIRS=(os.path.join(TEST_ROOT, 'project', 'faulty'),),
|
||||
STATICFILES_FINDERS=('django.contrib.staticfiles.finders.FileSystemFinder',),
|
||||
)
|
||||
def test_post_processing_failure(self):
|
||||
"""
|
||||
Test that post_processing indicates the origin of the error when it
|
||||
fails. Regression test for #18986.
|
||||
"""
|
||||
finders._finders.clear()
|
||||
err = six.StringIO()
|
||||
with self.assertRaises(Exception) as cm:
|
||||
call_command('collectstatic', interactive=False, verbosity=0, stderr=err)
|
||||
self.assertEqual("Post-processing 'faulty.css' failed!\n\n", err.getvalue())
|
||||
|
||||
|
||||
# we set DEBUG to False here since the template tag wouldn't work otherwise
|
||||
@override_settings(**dict(TEST_SETTINGS,
|
||||
|
||||
@@ -11,3 +11,4 @@ class EventSplitForm(forms.Form):
|
||||
class EventModelForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Event
|
||||
fields = '__all__'
|
||||
|
||||
@@ -203,6 +203,21 @@ class MergeDictTests(SimpleTestCase):
|
||||
('key2', ['value2', 'value3']),
|
||||
('key4', ['value5', 'value6'])])
|
||||
|
||||
def test_bool_casting(self):
|
||||
empty = MergeDict({}, {}, {})
|
||||
not_empty = MergeDict({}, {}, {"key": "value"})
|
||||
self.assertFalse(empty)
|
||||
self.assertTrue(not_empty)
|
||||
|
||||
def test_key_error(self):
|
||||
"""
|
||||
Test that the message of KeyError contains the missing key name.
|
||||
"""
|
||||
d1 = MergeDict({'key1': 42})
|
||||
with six.assertRaisesRegex(self, KeyError, 'key2'):
|
||||
d1['key2']
|
||||
|
||||
|
||||
class MultiValueDictTests(SimpleTestCase):
|
||||
|
||||
def test_multivaluedict(self):
|
||||
|
||||
@@ -152,3 +152,12 @@ class TestUtilsSimpleLazyObject(TestCase):
|
||||
SimpleLazyObject(None)
|
||||
finally:
|
||||
sys.settrace(old_trace_func)
|
||||
|
||||
def test_not_equal(self):
|
||||
lazy1 = SimpleLazyObject(lambda: 2)
|
||||
lazy2 = SimpleLazyObject(lambda: 2)
|
||||
lazy3 = SimpleLazyObject(lambda: 3)
|
||||
self.assertEqual(lazy1, lazy2)
|
||||
self.assertNotEqual(lazy1, lazy3)
|
||||
self.assertTrue(lazy1 != lazy3)
|
||||
self.assertFalse(lazy1 != lazy2)
|
||||
|
||||
@@ -217,5 +217,6 @@ class JavascriptI18nTests(LiveServerTestCase):
|
||||
def test_escaping(self):
|
||||
extended_apps = list(settings.INSTALLED_APPS) + ['view_tests']
|
||||
with self.settings(INSTALLED_APPS=extended_apps):
|
||||
response = self.client.get('%s%s' % (self.live_server_url, '/jsi18n_admin/'))
|
||||
# Force a language via GET otherwise the gettext functions are a noop!
|
||||
response = self.client.get('/jsi18n_admin/?language=de')
|
||||
self.assertContains(response, '\\x04')
|
||||
|
||||
Reference in New Issue
Block a user