parts/django/tests/regressiontests/modeladmin/tests.py
changeset 307 c6bca38c1cbf
equal deleted inserted replaced
306:5ff1fc726848 307:c6bca38c1cbf
       
     1 from datetime import date
       
     2 import unittest
       
     3 
       
     4 from django import forms
       
     5 from django.conf import settings
       
     6 from django.contrib.admin.options import ModelAdmin, TabularInline, \
       
     7     HORIZONTAL, VERTICAL
       
     8 from django.contrib.admin.sites import AdminSite
       
     9 from django.contrib.admin.validation import validate
       
    10 from django.contrib.admin.widgets import AdminDateWidget, AdminRadioSelect
       
    11 from django.core.exceptions import ImproperlyConfigured
       
    12 from django.forms.models import BaseModelFormSet
       
    13 from django.forms.widgets import Select
       
    14 from django.test import TestCase
       
    15 
       
    16 from models import Band, Concert, ValidationTestModel, \
       
    17     ValidationTestInlineModel
       
    18 
       
    19 
       
    20 # None of the following tests really depend on the content of the request,
       
    21 # so we'll just pass in None.
       
    22 request = None
       
    23 
       
    24 
       
    25 class ModelAdminTests(TestCase):
       
    26 
       
    27     def setUp(self):
       
    28         self.band = Band.objects.create(
       
    29             name='The Doors',
       
    30             bio='',
       
    31             sign_date=date(1965, 1, 1),
       
    32         )
       
    33         self.site = AdminSite()
       
    34 
       
    35     # form/fields/fieldsets interaction ##############################
       
    36 
       
    37     def test_default_fields(self):
       
    38         ma = ModelAdmin(Band, self.site)
       
    39 
       
    40         self.assertEquals(ma.get_form(request).base_fields.keys(),
       
    41             ['name', 'bio', 'sign_date'])
       
    42 
       
    43     def test_default_fieldsets(self):
       
    44         # fieldsets_add and fieldsets_change should return a special data structure that
       
    45         # is used in the templates. They should generate the "right thing" whether we
       
    46         # have specified a custom form, the fields argument, or nothing at all.
       
    47         #
       
    48         # Here's the default case. There are no custom form_add/form_change methods,
       
    49         # no fields argument, and no fieldsets argument.
       
    50         ma = ModelAdmin(Band, self.site)
       
    51         self.assertEqual(ma.get_fieldsets(request),
       
    52             [(None, {'fields': ['name', 'bio', 'sign_date']})])
       
    53 
       
    54         self.assertEqual(ma.get_fieldsets(request, self.band),
       
    55             [(None, {'fields': ['name', 'bio', 'sign_date']})])
       
    56 
       
    57     def test_field_arguments(self):
       
    58         # If we specify the fields argument, fieldsets_add and fielsets_change should
       
    59         # just stick the fields into a formsets structure and return it.
       
    60         class BandAdmin(ModelAdmin):
       
    61              fields = ['name']
       
    62 
       
    63         ma = BandAdmin(Band, self.site)
       
    64 
       
    65         self.assertEqual( ma.get_fieldsets(request),
       
    66             [(None, {'fields': ['name']})])
       
    67 
       
    68         self.assertEqual(ma.get_fieldsets(request, self.band),
       
    69             [(None, {'fields': ['name']})])
       
    70 
       
    71     def test_field_arguments_restricted_on_form(self):
       
    72         # If we specify fields or fieldsets, it should exclude fields on the Form class
       
    73         # to the fields specified. This may cause errors to be raised in the db layer if
       
    74         # required model fields arent in fields/fieldsets, but that's preferable to
       
    75         # ghost errors where you have a field in your Form class that isn't being
       
    76         # displayed because you forgot to add it to fields/fieldsets
       
    77 
       
    78         # Using `fields`.
       
    79         class BandAdmin(ModelAdmin):
       
    80             fields = ['name']
       
    81 
       
    82         ma = BandAdmin(Band, self.site)
       
    83         self.assertEqual(ma.get_form(request).base_fields.keys(), ['name'])
       
    84         self.assertEqual(ma.get_form(request, self.band).base_fields.keys(),
       
    85             ['name'])
       
    86 
       
    87         # Using `fieldsets`.
       
    88         class BandAdmin(ModelAdmin):
       
    89             fieldsets = [(None, {'fields': ['name']})]
       
    90 
       
    91         ma = BandAdmin(Band, self.site)
       
    92         self.assertEqual(ma.get_form(request).base_fields.keys(), ['name'])
       
    93         self.assertEqual(ma.get_form(request, self.band).base_fields.keys(),
       
    94             ['name'])
       
    95 
       
    96         # Using `exclude`.
       
    97         class BandAdmin(ModelAdmin):
       
    98             exclude = ['bio']
       
    99 
       
   100         ma = BandAdmin(Band, self.site)
       
   101         self.assertEqual(ma.get_form(request).base_fields.keys(),
       
   102             ['name', 'sign_date'])
       
   103 
       
   104         # You can also pass a tuple to `exclude`.
       
   105         class BandAdmin(ModelAdmin):
       
   106             exclude = ('bio',)
       
   107 
       
   108         ma = BandAdmin(Band, self.site)
       
   109         self.assertEqual(ma.get_form(request).base_fields.keys(),
       
   110             ['name', 'sign_date'])
       
   111 
       
   112         # Using `fields` and `exclude`.
       
   113         class BandAdmin(ModelAdmin):
       
   114             fields = ['name', 'bio']
       
   115             exclude = ['bio']
       
   116 
       
   117         ma = BandAdmin(Band, self.site)
       
   118         self.assertEqual(ma.get_form(request).base_fields.keys(),
       
   119             ['name'])
       
   120 
       
   121     def test_custom_form_validation(self):
       
   122         # If we specify a form, it should use it allowing custom validation to work
       
   123         # properly. This won't, however, break any of the admin widgets or media.
       
   124 
       
   125         class AdminBandForm(forms.ModelForm):
       
   126             delete = forms.BooleanField()
       
   127 
       
   128             class Meta:
       
   129                 model = Band
       
   130 
       
   131         class BandAdmin(ModelAdmin):
       
   132             form = AdminBandForm
       
   133 
       
   134         ma = BandAdmin(Band, self.site)
       
   135         self.assertEqual(ma.get_form(request).base_fields.keys(),
       
   136             ['name', 'bio', 'sign_date', 'delete'])
       
   137 
       
   138         self.assertEqual(
       
   139             type(ma.get_form(request).base_fields['sign_date'].widget),
       
   140             AdminDateWidget)
       
   141 
       
   142     def test_queryset_override(self):
       
   143         # If we need to override the queryset of a ModelChoiceField in our custom form
       
   144         # make sure that RelatedFieldWidgetWrapper doesn't mess that up.
       
   145 
       
   146         band2 = Band(name='The Beatles', bio='', sign_date=date(1962, 1, 1))
       
   147         band2.save()
       
   148 
       
   149         class ConcertAdmin(ModelAdmin):
       
   150             pass
       
   151         ma = ConcertAdmin(Concert, self.site)
       
   152         form = ma.get_form(request)()
       
   153 
       
   154         self.assertEqual(str(form["main_band"]),
       
   155             '<select name="main_band" id="id_main_band">\n'
       
   156             '<option value="" selected="selected">---------</option>\n'
       
   157             '<option value="%d">The Doors</option>\n'
       
   158             '<option value="%d">The Beatles</option>\n'
       
   159             '</select>' % (self.band.id, band2.id))
       
   160 
       
   161         class AdminConcertForm(forms.ModelForm):
       
   162             class Meta:
       
   163                 model = Concert
       
   164 
       
   165             def __init__(self, *args, **kwargs):
       
   166                 super(AdminConcertForm, self).__init__(*args, **kwargs)
       
   167                 self.fields["main_band"].queryset = Band.objects.filter(name='The Doors')
       
   168 
       
   169         class ConcertAdmin(ModelAdmin):
       
   170             form = AdminConcertForm
       
   171 
       
   172         ma = ConcertAdmin(Concert, self.site)
       
   173         form = ma.get_form(request)()
       
   174 
       
   175         self.assertEqual(str(form["main_band"]),
       
   176             '<select name="main_band" id="id_main_band">\n'
       
   177             '<option value="" selected="selected">---------</option>\n'
       
   178             '<option value="%d">The Doors</option>\n'
       
   179             '</select>' % self.band.id)
       
   180 
       
   181     # radio_fields behavior ###########################################
       
   182 
       
   183     def test_default_foreign_key_widget(self):
       
   184         # First, without any radio_fields specified, the widgets for ForeignKey
       
   185         # and fields with choices specified ought to be a basic Select widget.
       
   186         # ForeignKey widgets in the admin are wrapped with RelatedFieldWidgetWrapper so
       
   187         # they need to be handled properly when type checking. For Select fields, all of
       
   188         # the choices lists have a first entry of dashes.
       
   189 
       
   190         cma = ModelAdmin(Concert, self.site)
       
   191         cmafa = cma.get_form(request)
       
   192 
       
   193         self.assertEqual(type(cmafa.base_fields['main_band'].widget.widget),
       
   194             Select)
       
   195         self.assertEqual(
       
   196             list(cmafa.base_fields['main_band'].widget.choices),
       
   197             [(u'', u'---------'), (self.band.id, u'The Doors')])
       
   198 
       
   199         self.assertEqual(
       
   200             type(cmafa.base_fields['opening_band'].widget.widget), Select)
       
   201         self.assertEqual(
       
   202             list(cmafa.base_fields['opening_band'].widget.choices),
       
   203             [(u'', u'---------'), (self.band.id, u'The Doors')])
       
   204 
       
   205         self.assertEqual(type(cmafa.base_fields['day'].widget), Select)
       
   206         self.assertEqual(list(cmafa.base_fields['day'].widget.choices),
       
   207             [('', '---------'), (1, 'Fri'), (2, 'Sat')])
       
   208 
       
   209         self.assertEqual(type(cmafa.base_fields['transport'].widget),
       
   210             Select)
       
   211         self.assertEqual(
       
   212             list(cmafa.base_fields['transport'].widget.choices),
       
   213             [('', '---------'), (1, 'Plane'), (2, 'Train'), (3, 'Bus')])
       
   214 
       
   215     def test_foreign_key_as_radio_field(self):
       
   216         # Now specify all the fields as radio_fields.  Widgets should now be
       
   217         # RadioSelect, and the choices list should have a first entry of 'None' if
       
   218         # blank=True for the model field.  Finally, the widget should have the
       
   219         # 'radiolist' attr, and 'inline' as well if the field is specified HORIZONTAL.
       
   220 
       
   221         class ConcertAdmin(ModelAdmin):
       
   222             radio_fields = {
       
   223                 'main_band': HORIZONTAL,
       
   224                 'opening_band': VERTICAL,
       
   225                 'day': VERTICAL,
       
   226                 'transport': HORIZONTAL,
       
   227             }
       
   228 
       
   229         cma = ConcertAdmin(Concert, self.site)
       
   230         cmafa = cma.get_form(request)
       
   231 
       
   232         self.assertEqual(type(cmafa.base_fields['main_band'].widget.widget),
       
   233             AdminRadioSelect)
       
   234         self.assertEqual(cmafa.base_fields['main_band'].widget.attrs,
       
   235             {'class': 'radiolist inline'})
       
   236         self.assertEqual(list(cmafa.base_fields['main_band'].widget.choices),
       
   237             [(self.band.id, u'The Doors')])
       
   238 
       
   239         self.assertEqual(
       
   240             type(cmafa.base_fields['opening_band'].widget.widget),
       
   241             AdminRadioSelect)
       
   242         self.assertEqual(cmafa.base_fields['opening_band'].widget.attrs,
       
   243             {'class': 'radiolist'})
       
   244         self.assertEqual(
       
   245             list(cmafa.base_fields['opening_band'].widget.choices),
       
   246             [(u'', u'None'), (self.band.id, u'The Doors')])
       
   247 
       
   248         self.assertEqual(type(cmafa.base_fields['day'].widget),
       
   249             AdminRadioSelect)
       
   250         self.assertEqual(cmafa.base_fields['day'].widget.attrs,
       
   251             {'class': 'radiolist'})
       
   252         self.assertEqual(list(cmafa.base_fields['day'].widget.choices),
       
   253             [(1, 'Fri'), (2, 'Sat')])
       
   254 
       
   255         self.assertEqual(type(cmafa.base_fields['transport'].widget),
       
   256             AdminRadioSelect)
       
   257         self.assertEqual(cmafa.base_fields['transport'].widget.attrs,
       
   258             {'class': 'radiolist inline'})
       
   259         self.assertEqual(list(cmafa.base_fields['transport'].widget.choices),
       
   260             [('', u'None'), (1, 'Plane'), (2, 'Train'), (3, 'Bus')])
       
   261 
       
   262         class AdminConcertForm(forms.ModelForm):
       
   263             class Meta:
       
   264                 model = Concert
       
   265                 exclude = ('transport',)
       
   266 
       
   267         class ConcertAdmin(ModelAdmin):
       
   268             form = AdminConcertForm
       
   269 
       
   270         ma = ConcertAdmin(Concert, self.site)
       
   271         self.assertEqual(ma.get_form(request).base_fields.keys(),
       
   272             ['main_band', 'opening_band', 'day'])
       
   273 
       
   274         class AdminConcertForm(forms.ModelForm):
       
   275             extra = forms.CharField()
       
   276 
       
   277             class Meta:
       
   278                 model = Concert
       
   279                 fields = ['extra', 'transport']
       
   280 
       
   281         class ConcertAdmin(ModelAdmin):
       
   282             form = AdminConcertForm
       
   283 
       
   284         ma = ConcertAdmin(Concert, self.site)
       
   285         self.assertEqual(ma.get_form(request).base_fields.keys(),
       
   286             ['extra', 'transport'])
       
   287 
       
   288         class ConcertInline(TabularInline):
       
   289             form = AdminConcertForm
       
   290             model = Concert
       
   291             fk_name = 'main_band'
       
   292             can_delete = True
       
   293 
       
   294         class BandAdmin(ModelAdmin):
       
   295             inlines = [
       
   296                 ConcertInline
       
   297             ]
       
   298 
       
   299         ma = BandAdmin(Band, self.site)
       
   300         self.assertEqual(
       
   301             list(ma.get_formsets(request))[0]().forms[0].fields.keys(),
       
   302             ['extra', 'transport', 'id', 'DELETE', 'main_band'])
       
   303 
       
   304 
       
   305 class ValidationTests(unittest.TestCase):
       
   306     def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs):
       
   307         self.assertRaises(error, callable, *args, **kwargs)
       
   308         try:
       
   309             callable(*args, **kwargs)
       
   310         except error, e:
       
   311             self.assertEqual(message, str(e))
       
   312 
       
   313     def test_validation_only_runs_in_debug(self):
       
   314         # Ensure validation only runs when DEBUG = True
       
   315         try:
       
   316             settings.DEBUG = True
       
   317 
       
   318             class ValidationTestModelAdmin(ModelAdmin):
       
   319                 raw_id_fields = 10
       
   320 
       
   321             site = AdminSite()
       
   322 
       
   323             self.assertRaisesErrorWithMessage(
       
   324                 ImproperlyConfigured,
       
   325                 "'ValidationTestModelAdmin.raw_id_fields' must be a list or tuple.",
       
   326                 site.register,
       
   327                 ValidationTestModel,
       
   328                 ValidationTestModelAdmin,
       
   329             )
       
   330         finally:
       
   331             settings.DEBUG = False
       
   332 
       
   333         site = AdminSite()
       
   334         site.register(ValidationTestModel, ValidationTestModelAdmin)
       
   335 
       
   336     def test_raw_id_fields_validation(self):
       
   337 
       
   338         class ValidationTestModelAdmin(ModelAdmin):
       
   339             raw_id_fields = 10
       
   340 
       
   341         self.assertRaisesErrorWithMessage(
       
   342             ImproperlyConfigured,
       
   343             "'ValidationTestModelAdmin.raw_id_fields' must be a list or tuple.",
       
   344             validate,
       
   345             ValidationTestModelAdmin,
       
   346             ValidationTestModel,
       
   347         )
       
   348 
       
   349         class ValidationTestModelAdmin(ModelAdmin):
       
   350             raw_id_fields = ('non_existent_field',)
       
   351 
       
   352         self.assertRaisesErrorWithMessage(
       
   353             ImproperlyConfigured,
       
   354             "'ValidationTestModelAdmin.raw_id_fields' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   355             validate,
       
   356             ValidationTestModelAdmin,
       
   357             ValidationTestModel,
       
   358         )
       
   359 
       
   360         class ValidationTestModelAdmin(ModelAdmin):
       
   361             raw_id_fields = ('name',)
       
   362 
       
   363         self.assertRaisesErrorWithMessage(
       
   364             ImproperlyConfigured,
       
   365             "'ValidationTestModelAdmin.raw_id_fields[0]', 'name' must be either a ForeignKey or ManyToManyField.",
       
   366             validate,
       
   367             ValidationTestModelAdmin,
       
   368             ValidationTestModel,
       
   369         )
       
   370 
       
   371         class ValidationTestModelAdmin(ModelAdmin):
       
   372             raw_id_fields = ('users',)
       
   373 
       
   374         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   375 
       
   376     def test_fieldsets_validation(self):
       
   377 
       
   378         class ValidationTestModelAdmin(ModelAdmin):
       
   379             fieldsets = 10
       
   380 
       
   381         self.assertRaisesErrorWithMessage(
       
   382             ImproperlyConfigured,
       
   383             "'ValidationTestModelAdmin.fieldsets' must be a list or tuple.",
       
   384             validate,
       
   385             ValidationTestModelAdmin,
       
   386             ValidationTestModel,
       
   387         )
       
   388 
       
   389         class ValidationTestModelAdmin(ModelAdmin):
       
   390             fieldsets = ({},)
       
   391 
       
   392         self.assertRaisesErrorWithMessage(
       
   393             ImproperlyConfigured,
       
   394             "'ValidationTestModelAdmin.fieldsets[0]' must be a list or tuple.",
       
   395             validate,
       
   396             ValidationTestModelAdmin,
       
   397             ValidationTestModel,
       
   398         )
       
   399 
       
   400         class ValidationTestModelAdmin(ModelAdmin):
       
   401             fieldsets = ((),)
       
   402 
       
   403         self.assertRaisesErrorWithMessage(
       
   404             ImproperlyConfigured,
       
   405             "'ValidationTestModelAdmin.fieldsets[0]' does not have exactly two elements.",
       
   406             validate,
       
   407             ValidationTestModelAdmin,
       
   408             ValidationTestModel,
       
   409         )
       
   410 
       
   411         class ValidationTestModelAdmin(ModelAdmin):
       
   412             fieldsets = (("General", ()),)
       
   413 
       
   414         self.assertRaisesErrorWithMessage(
       
   415             ImproperlyConfigured,
       
   416             "'ValidationTestModelAdmin.fieldsets[0][1]' must be a dictionary.",
       
   417             validate,
       
   418             ValidationTestModelAdmin,
       
   419             ValidationTestModel,
       
   420         )
       
   421 
       
   422         class ValidationTestModelAdmin(ModelAdmin):
       
   423             fieldsets = (("General", {}),)
       
   424 
       
   425         self.assertRaisesErrorWithMessage(
       
   426             ImproperlyConfigured,
       
   427             "'fields' key is required in ValidationTestModelAdmin.fieldsets[0][1] field options dict.",
       
   428             validate,
       
   429             ValidationTestModelAdmin,
       
   430             ValidationTestModel,
       
   431         )
       
   432 
       
   433         class ValidationTestModelAdmin(ModelAdmin):
       
   434             fieldsets = (("General", {"fields": ("non_existent_field",)}),)
       
   435 
       
   436         self.assertRaisesErrorWithMessage(
       
   437             ImproperlyConfigured,
       
   438             "'ValidationTestModelAdmin.fieldsets[0][1]['fields']' refers to field 'non_existent_field' that is missing from the form.",
       
   439             validate,
       
   440             ValidationTestModelAdmin,
       
   441             ValidationTestModel,
       
   442         )
       
   443 
       
   444         class ValidationTestModelAdmin(ModelAdmin):
       
   445             fieldsets = (("General", {"fields": ("name",)}),)
       
   446 
       
   447         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   448 
       
   449         class ValidationTestModelAdmin(ModelAdmin):
       
   450             fieldsets = (("General", {"fields": ("name",)}),)
       
   451             fields = ["name",]
       
   452 
       
   453         self.assertRaisesErrorWithMessage(
       
   454             ImproperlyConfigured,
       
   455             "Both fieldsets and fields are specified in ValidationTestModelAdmin.",
       
   456             validate,
       
   457             ValidationTestModelAdmin,
       
   458             ValidationTestModel,
       
   459         )
       
   460 
       
   461         class ValidationTestModelAdmin(ModelAdmin):
       
   462             fieldsets = [(None, {'fields': ['name', 'name']})]
       
   463 
       
   464         self.assertRaisesErrorWithMessage(
       
   465             ImproperlyConfigured,
       
   466             "There are duplicate field(s) in ValidationTestModelAdmin.fieldsets",
       
   467             validate,
       
   468             ValidationTestModelAdmin,
       
   469             ValidationTestModel,
       
   470         )
       
   471 
       
   472         class ValidationTestModelAdmin(ModelAdmin):
       
   473             fields = ["name", "name"]
       
   474 
       
   475         self.assertRaisesErrorWithMessage(
       
   476             ImproperlyConfigured,
       
   477             "There are duplicate field(s) in ValidationTestModelAdmin.fields",
       
   478             validate,
       
   479             ValidationTestModelAdmin,
       
   480             ValidationTestModel,
       
   481         )
       
   482 
       
   483     def test_form_validation(self):
       
   484 
       
   485         class FakeForm(object):
       
   486             pass
       
   487 
       
   488         class ValidationTestModelAdmin(ModelAdmin):
       
   489             form = FakeForm
       
   490 
       
   491         self.assertRaisesErrorWithMessage(
       
   492             ImproperlyConfigured,
       
   493             "ValidationTestModelAdmin.form does not inherit from BaseModelForm.",
       
   494             validate,
       
   495             ValidationTestModelAdmin,
       
   496             ValidationTestModel,
       
   497         )
       
   498 
       
   499     def test_fieldsets_with_custom_form_validation(self):
       
   500 
       
   501         class BandAdmin(ModelAdmin):
       
   502 
       
   503             fieldsets = (
       
   504                 ('Band', {
       
   505                     'fields': ('non_existent_field',)
       
   506                 }),
       
   507             )
       
   508 
       
   509         self.assertRaisesErrorWithMessage(
       
   510             ImproperlyConfigured,
       
   511             "'BandAdmin.fieldsets[0][1]['fields']' refers to field 'non_existent_field' that is missing from the form.",
       
   512             validate,
       
   513             BandAdmin,
       
   514             Band,
       
   515         )
       
   516 
       
   517         class BandAdmin(ModelAdmin):
       
   518             fieldsets = (
       
   519                 ('Band', {
       
   520                     'fields': ('name',)
       
   521                 }),
       
   522             )
       
   523 
       
   524         validate(BandAdmin, Band)
       
   525 
       
   526         class AdminBandForm(forms.ModelForm):
       
   527             class Meta:
       
   528                 model = Band
       
   529 
       
   530         class BandAdmin(ModelAdmin):
       
   531             form = AdminBandForm
       
   532 
       
   533             fieldsets = (
       
   534                 ('Band', {
       
   535                     'fields': ('non_existent_field',)
       
   536                 }),
       
   537             )
       
   538 
       
   539         self.assertRaisesErrorWithMessage(
       
   540             ImproperlyConfigured,
       
   541             "'BandAdmin.fieldsets[0][1]['fields']' refers to field 'non_existent_field' that is missing from the form.",
       
   542             validate,
       
   543             BandAdmin,
       
   544             Band,
       
   545         )
       
   546 
       
   547         class AdminBandForm(forms.ModelForm):
       
   548             delete = forms.BooleanField()
       
   549 
       
   550             class Meta:
       
   551                 model = Band
       
   552 
       
   553         class BandAdmin(ModelAdmin):
       
   554             form = AdminBandForm
       
   555 
       
   556             fieldsets = (
       
   557                 ('Band', {
       
   558                     'fields': ('name', 'bio', 'sign_date', 'delete')
       
   559                 }),
       
   560             )
       
   561 
       
   562         validate(BandAdmin, Band)
       
   563 
       
   564     def test_filter_vertical_validation(self):
       
   565 
       
   566         class ValidationTestModelAdmin(ModelAdmin):
       
   567             filter_vertical = 10
       
   568 
       
   569         self.assertRaisesErrorWithMessage(
       
   570             ImproperlyConfigured,
       
   571             "'ValidationTestModelAdmin.filter_vertical' must be a list or tuple.",
       
   572             validate,
       
   573             ValidationTestModelAdmin,
       
   574             ValidationTestModel,
       
   575         )
       
   576 
       
   577         class ValidationTestModelAdmin(ModelAdmin):
       
   578             filter_vertical = ("non_existent_field",)
       
   579 
       
   580         self.assertRaisesErrorWithMessage(
       
   581             ImproperlyConfigured,
       
   582             "'ValidationTestModelAdmin.filter_vertical' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   583             validate,
       
   584             ValidationTestModelAdmin,
       
   585             ValidationTestModel,
       
   586         )
       
   587 
       
   588         class ValidationTestModelAdmin(ModelAdmin):
       
   589             filter_vertical = ("name",)
       
   590 
       
   591         self.assertRaisesErrorWithMessage(
       
   592             ImproperlyConfigured,
       
   593             "'ValidationTestModelAdmin.filter_vertical[0]' must be a ManyToManyField.",
       
   594             validate,
       
   595             ValidationTestModelAdmin,
       
   596             ValidationTestModel,
       
   597         )
       
   598 
       
   599         class ValidationTestModelAdmin(ModelAdmin):
       
   600             filter_vertical = ("users",)
       
   601 
       
   602         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   603 
       
   604     def test_filter_horizontal_validation(self):
       
   605 
       
   606         class ValidationTestModelAdmin(ModelAdmin):
       
   607             filter_horizontal = 10
       
   608 
       
   609         self.assertRaisesErrorWithMessage(
       
   610             ImproperlyConfigured,
       
   611             "'ValidationTestModelAdmin.filter_horizontal' must be a list or tuple.",
       
   612             validate,
       
   613             ValidationTestModelAdmin,
       
   614             ValidationTestModel,
       
   615         )
       
   616 
       
   617         class ValidationTestModelAdmin(ModelAdmin):
       
   618             filter_horizontal = ("non_existent_field",)
       
   619 
       
   620         self.assertRaisesErrorWithMessage(
       
   621             ImproperlyConfigured,
       
   622             "'ValidationTestModelAdmin.filter_horizontal' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   623             validate,
       
   624             ValidationTestModelAdmin,
       
   625             ValidationTestModel,
       
   626         )
       
   627 
       
   628         class ValidationTestModelAdmin(ModelAdmin):
       
   629             filter_horizontal = ("name",)
       
   630 
       
   631         self.assertRaisesErrorWithMessage(
       
   632             ImproperlyConfigured,
       
   633             "'ValidationTestModelAdmin.filter_horizontal[0]' must be a ManyToManyField.",
       
   634             validate,
       
   635             ValidationTestModelAdmin,
       
   636             ValidationTestModel,
       
   637         )
       
   638 
       
   639         class ValidationTestModelAdmin(ModelAdmin):
       
   640             filter_horizontal = ("users",)
       
   641 
       
   642         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   643 
       
   644     def test_radio_fields_validation(self):
       
   645 
       
   646         class ValidationTestModelAdmin(ModelAdmin):
       
   647             radio_fields = ()
       
   648 
       
   649         self.assertRaisesErrorWithMessage(
       
   650             ImproperlyConfigured,
       
   651             "'ValidationTestModelAdmin.radio_fields' must be a dictionary.",
       
   652             validate,
       
   653             ValidationTestModelAdmin,
       
   654             ValidationTestModel,
       
   655         )
       
   656 
       
   657         class ValidationTestModelAdmin(ModelAdmin):
       
   658             radio_fields = {"non_existent_field": None}
       
   659 
       
   660         self.assertRaisesErrorWithMessage(
       
   661             ImproperlyConfigured,
       
   662             "'ValidationTestModelAdmin.radio_fields' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   663             validate,
       
   664             ValidationTestModelAdmin,
       
   665             ValidationTestModel,
       
   666         )
       
   667 
       
   668         class ValidationTestModelAdmin(ModelAdmin):
       
   669             radio_fields = {"name": None}
       
   670 
       
   671         self.assertRaisesErrorWithMessage(
       
   672             ImproperlyConfigured,
       
   673             "'ValidationTestModelAdmin.radio_fields['name']' is neither an instance of ForeignKey nor does have choices set.",
       
   674             validate,
       
   675             ValidationTestModelAdmin,
       
   676             ValidationTestModel,
       
   677         )
       
   678 
       
   679         class ValidationTestModelAdmin(ModelAdmin):
       
   680             radio_fields = {"state": None}
       
   681 
       
   682         self.assertRaisesErrorWithMessage(
       
   683             ImproperlyConfigured,
       
   684             "'ValidationTestModelAdmin.radio_fields['state']' is neither admin.HORIZONTAL nor admin.VERTICAL.",
       
   685             validate,
       
   686             ValidationTestModelAdmin,
       
   687             ValidationTestModel,
       
   688         )
       
   689 
       
   690         class ValidationTestModelAdmin(ModelAdmin):
       
   691             radio_fields = {"state": VERTICAL}
       
   692 
       
   693         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   694 
       
   695     def test_prepopulated_fields_validation(self):
       
   696 
       
   697         class ValidationTestModelAdmin(ModelAdmin):
       
   698             prepopulated_fields = ()
       
   699 
       
   700         self.assertRaisesErrorWithMessage(
       
   701             ImproperlyConfigured,
       
   702             "'ValidationTestModelAdmin.prepopulated_fields' must be a dictionary.",
       
   703             validate,
       
   704             ValidationTestModelAdmin,
       
   705             ValidationTestModel,
       
   706         )
       
   707 
       
   708         class ValidationTestModelAdmin(ModelAdmin):
       
   709             prepopulated_fields = {"non_existent_field": None}
       
   710 
       
   711         self.assertRaisesErrorWithMessage(
       
   712             ImproperlyConfigured,
       
   713             "'ValidationTestModelAdmin.prepopulated_fields' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   714             validate,
       
   715             ValidationTestModelAdmin,
       
   716             ValidationTestModel,
       
   717         )
       
   718 
       
   719         class ValidationTestModelAdmin(ModelAdmin):
       
   720             prepopulated_fields = {"slug": ("non_existent_field",)}
       
   721 
       
   722         self.assertRaisesErrorWithMessage(
       
   723             ImproperlyConfigured,
       
   724             "'ValidationTestModelAdmin.prepopulated_fields['slug'][0]' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   725             validate,
       
   726             ValidationTestModelAdmin,
       
   727             ValidationTestModel,
       
   728         )
       
   729 
       
   730         class ValidationTestModelAdmin(ModelAdmin):
       
   731             prepopulated_fields = {"users": ("name",)}
       
   732 
       
   733         self.assertRaisesErrorWithMessage(
       
   734             ImproperlyConfigured,
       
   735             "'ValidationTestModelAdmin.prepopulated_fields['users']' is either a DateTimeField, ForeignKey or ManyToManyField. This isn't allowed.",
       
   736             validate,
       
   737             ValidationTestModelAdmin,
       
   738             ValidationTestModel,
       
   739         )
       
   740 
       
   741         class ValidationTestModelAdmin(ModelAdmin):
       
   742             prepopulated_fields = {"slug": ("name",)}
       
   743 
       
   744         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   745 
       
   746     def test_list_display_validation(self):
       
   747 
       
   748         class ValidationTestModelAdmin(ModelAdmin):
       
   749             list_display = 10
       
   750 
       
   751         self.assertRaisesErrorWithMessage(
       
   752             ImproperlyConfigured,
       
   753             "'ValidationTestModelAdmin.list_display' must be a list or tuple.",
       
   754             validate,
       
   755             ValidationTestModelAdmin,
       
   756             ValidationTestModel,
       
   757         )
       
   758 
       
   759         class ValidationTestModelAdmin(ModelAdmin):
       
   760             list_display = ('non_existent_field',)
       
   761 
       
   762         self.assertRaisesErrorWithMessage(
       
   763             ImproperlyConfigured,
       
   764             "ValidationTestModelAdmin.list_display[0], 'non_existent_field' is not a callable or an attribute of 'ValidationTestModelAdmin' or found in the model 'ValidationTestModel'.",
       
   765             validate,
       
   766             ValidationTestModelAdmin,
       
   767             ValidationTestModel,
       
   768         )
       
   769 
       
   770         class ValidationTestModelAdmin(ModelAdmin):
       
   771             list_display = ('users',)
       
   772 
       
   773         self.assertRaisesErrorWithMessage(
       
   774             ImproperlyConfigured,
       
   775             "'ValidationTestModelAdmin.list_display[0]', 'users' is a ManyToManyField which is not supported.",
       
   776             validate,
       
   777             ValidationTestModelAdmin,
       
   778             ValidationTestModel,
       
   779         )
       
   780 
       
   781         class ValidationTestModelAdmin(ModelAdmin):
       
   782             list_display = ('name',)
       
   783 
       
   784         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   785 
       
   786     def test_list_display_links_validation(self):
       
   787 
       
   788         class ValidationTestModelAdmin(ModelAdmin):
       
   789             list_display_links = 10
       
   790 
       
   791         self.assertRaisesErrorWithMessage(
       
   792             ImproperlyConfigured,
       
   793             "'ValidationTestModelAdmin.list_display_links' must be a list or tuple.",
       
   794             validate,
       
   795             ValidationTestModelAdmin,
       
   796             ValidationTestModel,
       
   797         )
       
   798 
       
   799         class ValidationTestModelAdmin(ModelAdmin):
       
   800             list_display_links = ('non_existent_field',)
       
   801 
       
   802         self.assertRaisesErrorWithMessage(
       
   803             ImproperlyConfigured,
       
   804             "'ValidationTestModelAdmin.list_display_links[0]' refers to 'non_existent_field' that is neither a field, method or property of model 'ValidationTestModel'.",
       
   805             validate,
       
   806             ValidationTestModelAdmin,
       
   807             ValidationTestModel,
       
   808         )
       
   809 
       
   810         class ValidationTestModelAdmin(ModelAdmin):
       
   811             list_display_links = ('name',)
       
   812 
       
   813         self.assertRaisesErrorWithMessage(
       
   814             ImproperlyConfigured,
       
   815             "'ValidationTestModelAdmin.list_display_links[0]'refers to 'name' which is not defined in 'list_display'.",
       
   816             validate,
       
   817             ValidationTestModelAdmin,
       
   818             ValidationTestModel,
       
   819         )
       
   820 
       
   821         class ValidationTestModelAdmin(ModelAdmin):
       
   822             list_display = ('name',)
       
   823             list_display_links = ('name',)
       
   824 
       
   825         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   826 
       
   827     def test_list_filter_validation(self):
       
   828 
       
   829         class ValidationTestModelAdmin(ModelAdmin):
       
   830             list_filter = 10
       
   831 
       
   832         self.assertRaisesErrorWithMessage(
       
   833             ImproperlyConfigured,
       
   834             "'ValidationTestModelAdmin.list_filter' must be a list or tuple.",
       
   835             validate,
       
   836             ValidationTestModelAdmin,
       
   837             ValidationTestModel,
       
   838         )
       
   839 
       
   840         class ValidationTestModelAdmin(ModelAdmin):
       
   841             list_filter = ('non_existent_field',)
       
   842 
       
   843         self.assertRaisesErrorWithMessage(
       
   844             ImproperlyConfigured,
       
   845             "'ValidationTestModelAdmin.list_filter[0]' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   846             validate,
       
   847             ValidationTestModelAdmin,
       
   848             ValidationTestModel,
       
   849         )
       
   850 
       
   851         class ValidationTestModelAdmin(ModelAdmin):
       
   852             list_filter = ('is_active',)
       
   853 
       
   854         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   855 
       
   856     def test_list_per_page_validation(self):
       
   857 
       
   858         class ValidationTestModelAdmin(ModelAdmin):
       
   859             list_per_page = 'hello'
       
   860 
       
   861         self.assertRaisesErrorWithMessage(
       
   862             ImproperlyConfigured,
       
   863             "'ValidationTestModelAdmin.list_per_page' should be a integer.",
       
   864             validate,
       
   865             ValidationTestModelAdmin,
       
   866             ValidationTestModel,
       
   867         )
       
   868 
       
   869         class ValidationTestModelAdmin(ModelAdmin):
       
   870             list_per_page = 100
       
   871 
       
   872         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   873 
       
   874     def test_search_fields_validation(self):
       
   875 
       
   876         class ValidationTestModelAdmin(ModelAdmin):
       
   877             search_fields = 10
       
   878 
       
   879         self.assertRaisesErrorWithMessage(
       
   880             ImproperlyConfigured,
       
   881             "'ValidationTestModelAdmin.search_fields' must be a list or tuple.",
       
   882             validate,
       
   883             ValidationTestModelAdmin,
       
   884             ValidationTestModel,
       
   885         )
       
   886 
       
   887     def test_date_hierarchy_validation(self):
       
   888 
       
   889         class ValidationTestModelAdmin(ModelAdmin):
       
   890             date_hierarchy = 'non_existent_field'
       
   891 
       
   892         self.assertRaisesErrorWithMessage(
       
   893             ImproperlyConfigured,
       
   894             "'ValidationTestModelAdmin.date_hierarchy' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   895             validate,
       
   896             ValidationTestModelAdmin,
       
   897             ValidationTestModel,
       
   898         )
       
   899 
       
   900         class ValidationTestModelAdmin(ModelAdmin):
       
   901             date_hierarchy = 'name'
       
   902 
       
   903         self.assertRaisesErrorWithMessage(
       
   904             ImproperlyConfigured,
       
   905             "'ValidationTestModelAdmin.date_hierarchy is neither an instance of DateField nor DateTimeField.",
       
   906             validate,
       
   907             ValidationTestModelAdmin,
       
   908             ValidationTestModel,
       
   909         )
       
   910 
       
   911         class ValidationTestModelAdmin(ModelAdmin):
       
   912             date_hierarchy = 'pub_date'
       
   913 
       
   914         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   915 
       
   916     def test_ordering_validation(self):
       
   917 
       
   918         class ValidationTestModelAdmin(ModelAdmin):
       
   919             ordering = 10
       
   920 
       
   921         self.assertRaisesErrorWithMessage(
       
   922             ImproperlyConfigured,
       
   923             "'ValidationTestModelAdmin.ordering' must be a list or tuple.",
       
   924             validate,
       
   925             ValidationTestModelAdmin,
       
   926             ValidationTestModel,
       
   927         )
       
   928 
       
   929         class ValidationTestModelAdmin(ModelAdmin):
       
   930             ordering = ('non_existent_field',)
       
   931 
       
   932         self.assertRaisesErrorWithMessage(
       
   933             ImproperlyConfigured,
       
   934             "'ValidationTestModelAdmin.ordering[0]' refers to field 'non_existent_field' that is missing from model 'ValidationTestModel'.",
       
   935             validate,
       
   936             ValidationTestModelAdmin,
       
   937             ValidationTestModel,
       
   938         )
       
   939 
       
   940         class ValidationTestModelAdmin(ModelAdmin):
       
   941             ordering = ('?', 'name')
       
   942 
       
   943         self.assertRaisesErrorWithMessage(
       
   944             ImproperlyConfigured,
       
   945             "'ValidationTestModelAdmin.ordering' has the random ordering marker '?', but contains other fields as well. Please either remove '?' or the other fields.",
       
   946             validate,
       
   947             ValidationTestModelAdmin,
       
   948             ValidationTestModel,
       
   949         )
       
   950 
       
   951         class ValidationTestModelAdmin(ModelAdmin):
       
   952             ordering = ('?',)
       
   953 
       
   954         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   955 
       
   956         class ValidationTestModelAdmin(ModelAdmin):
       
   957             ordering = ('band__name',)
       
   958 
       
   959         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   960 
       
   961         class ValidationTestModelAdmin(ModelAdmin):
       
   962             ordering = ('name',)
       
   963 
       
   964         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   965 
       
   966     def test_list_select_related_validation(self):
       
   967 
       
   968         class ValidationTestModelAdmin(ModelAdmin):
       
   969             list_select_related = 1
       
   970 
       
   971         self.assertRaisesErrorWithMessage(
       
   972             ImproperlyConfigured,
       
   973             "'ValidationTestModelAdmin.list_select_related' should be a boolean.",
       
   974             validate,
       
   975             ValidationTestModelAdmin,
       
   976             ValidationTestModel,
       
   977         )
       
   978 
       
   979         class ValidationTestModelAdmin(ModelAdmin):
       
   980             list_select_related = False
       
   981 
       
   982         validate(ValidationTestModelAdmin, ValidationTestModel)
       
   983 
       
   984     def test_save_as_validation(self):
       
   985 
       
   986         class ValidationTestModelAdmin(ModelAdmin):
       
   987             save_as = 1
       
   988 
       
   989         self.assertRaisesErrorWithMessage(
       
   990             ImproperlyConfigured,
       
   991             "'ValidationTestModelAdmin.save_as' should be a boolean.",
       
   992             validate,
       
   993             ValidationTestModelAdmin,
       
   994             ValidationTestModel,
       
   995         )
       
   996 
       
   997         class ValidationTestModelAdmin(ModelAdmin):
       
   998             save_as = True
       
   999 
       
  1000         validate(ValidationTestModelAdmin, ValidationTestModel)
       
  1001 
       
  1002     def test_save_on_top_validation(self):
       
  1003 
       
  1004         class ValidationTestModelAdmin(ModelAdmin):
       
  1005             save_on_top = 1
       
  1006 
       
  1007         self.assertRaisesErrorWithMessage(
       
  1008             ImproperlyConfigured,
       
  1009             "'ValidationTestModelAdmin.save_on_top' should be a boolean.",
       
  1010             validate,
       
  1011             ValidationTestModelAdmin,
       
  1012             ValidationTestModel,
       
  1013         )
       
  1014 
       
  1015         class ValidationTestModelAdmin(ModelAdmin):
       
  1016             save_on_top = True
       
  1017 
       
  1018         validate(ValidationTestModelAdmin, ValidationTestModel)
       
  1019 
       
  1020     def test_inlines_validation(self):
       
  1021 
       
  1022         class ValidationTestModelAdmin(ModelAdmin):
       
  1023             inlines = 10
       
  1024 
       
  1025         self.assertRaisesErrorWithMessage(
       
  1026             ImproperlyConfigured,
       
  1027             "'ValidationTestModelAdmin.inlines' must be a list or tuple.",
       
  1028             validate,
       
  1029             ValidationTestModelAdmin,
       
  1030             ValidationTestModel,
       
  1031         )
       
  1032 
       
  1033         class ValidationTestInline(object):
       
  1034             pass
       
  1035 
       
  1036         class ValidationTestModelAdmin(ModelAdmin):
       
  1037             inlines = [ValidationTestInline]
       
  1038 
       
  1039         self.assertRaisesErrorWithMessage(
       
  1040             ImproperlyConfigured,
       
  1041             "'ValidationTestModelAdmin.inlines[0]' does not inherit from BaseModelAdmin.",
       
  1042             validate,
       
  1043             ValidationTestModelAdmin,
       
  1044             ValidationTestModel,
       
  1045         )
       
  1046 
       
  1047         class ValidationTestInline(TabularInline):
       
  1048             pass
       
  1049 
       
  1050         class ValidationTestModelAdmin(ModelAdmin):
       
  1051             inlines = [ValidationTestInline]
       
  1052 
       
  1053         self.assertRaisesErrorWithMessage(
       
  1054             ImproperlyConfigured,
       
  1055             "'model' is a required attribute of 'ValidationTestModelAdmin.inlines[0]'.",
       
  1056             validate,
       
  1057             ValidationTestModelAdmin,
       
  1058             ValidationTestModel,
       
  1059         )
       
  1060 
       
  1061         class SomethingBad(object):
       
  1062             pass
       
  1063 
       
  1064         class ValidationTestInline(TabularInline):
       
  1065             model = SomethingBad
       
  1066 
       
  1067         class ValidationTestModelAdmin(ModelAdmin):
       
  1068             inlines = [ValidationTestInline]
       
  1069 
       
  1070         self.assertRaisesErrorWithMessage(
       
  1071             ImproperlyConfigured,
       
  1072             "'ValidationTestModelAdmin.inlines[0].model' does not inherit from models.Model.",
       
  1073             validate,
       
  1074             ValidationTestModelAdmin,
       
  1075             ValidationTestModel,
       
  1076         )
       
  1077 
       
  1078         class ValidationTestInline(TabularInline):
       
  1079             model = ValidationTestInlineModel
       
  1080 
       
  1081         class ValidationTestModelAdmin(ModelAdmin):
       
  1082             inlines = [ValidationTestInline]
       
  1083 
       
  1084         validate(ValidationTestModelAdmin, ValidationTestModel)
       
  1085 
       
  1086     def test_fields_validation(self):
       
  1087 
       
  1088         class ValidationTestInline(TabularInline):
       
  1089             model = ValidationTestInlineModel
       
  1090             fields = 10
       
  1091 
       
  1092         class ValidationTestModelAdmin(ModelAdmin):
       
  1093             inlines = [ValidationTestInline]
       
  1094 
       
  1095         self.assertRaisesErrorWithMessage(
       
  1096             ImproperlyConfigured,
       
  1097             "'ValidationTestInline.fields' must be a list or tuple.",
       
  1098             validate,
       
  1099             ValidationTestModelAdmin,
       
  1100             ValidationTestModel,
       
  1101         )
       
  1102 
       
  1103         class ValidationTestInline(TabularInline):
       
  1104             model = ValidationTestInlineModel
       
  1105             fields = ("non_existent_field",)
       
  1106 
       
  1107         class ValidationTestModelAdmin(ModelAdmin):
       
  1108             inlines = [ValidationTestInline]
       
  1109 
       
  1110         self.assertRaisesErrorWithMessage(
       
  1111             ImproperlyConfigured,
       
  1112             "'ValidationTestInline.fields' refers to field 'non_existent_field' that is missing from the form.",
       
  1113             validate,
       
  1114             ValidationTestModelAdmin,
       
  1115             ValidationTestModel,
       
  1116         )
       
  1117 
       
  1118     def test_fk_name_validation(self):
       
  1119 
       
  1120         class ValidationTestInline(TabularInline):
       
  1121             model = ValidationTestInlineModel
       
  1122             fk_name = "non_existent_field"
       
  1123 
       
  1124         class ValidationTestModelAdmin(ModelAdmin):
       
  1125             inlines = [ValidationTestInline]
       
  1126 
       
  1127         self.assertRaisesErrorWithMessage(
       
  1128             ImproperlyConfigured,
       
  1129             "'ValidationTestInline.fk_name' refers to field 'non_existent_field' that is missing from model 'ValidationTestInlineModel'.",
       
  1130             validate,
       
  1131             ValidationTestModelAdmin,
       
  1132             ValidationTestModel,
       
  1133         )
       
  1134 
       
  1135         class ValidationTestInline(TabularInline):
       
  1136             model = ValidationTestInlineModel
       
  1137             fk_name = "parent"
       
  1138 
       
  1139         class ValidationTestModelAdmin(ModelAdmin):
       
  1140             inlines = [ValidationTestInline]
       
  1141 
       
  1142         validate(ValidationTestModelAdmin, ValidationTestModel)
       
  1143 
       
  1144     def test_extra_validation(self):
       
  1145 
       
  1146         class ValidationTestInline(TabularInline):
       
  1147             model = ValidationTestInlineModel
       
  1148             extra = "hello"
       
  1149 
       
  1150         class ValidationTestModelAdmin(ModelAdmin):
       
  1151             inlines = [ValidationTestInline]
       
  1152 
       
  1153         self.assertRaisesErrorWithMessage(
       
  1154             ImproperlyConfigured,
       
  1155             "'ValidationTestInline.extra' should be a integer.",
       
  1156             validate,
       
  1157             ValidationTestModelAdmin,
       
  1158             ValidationTestModel,
       
  1159         )
       
  1160 
       
  1161         class ValidationTestInline(TabularInline):
       
  1162             model = ValidationTestInlineModel
       
  1163             extra = 2
       
  1164 
       
  1165         class ValidationTestModelAdmin(ModelAdmin):
       
  1166             inlines = [ValidationTestInline]
       
  1167 
       
  1168         validate(ValidationTestModelAdmin, ValidationTestModel)
       
  1169 
       
  1170     def test_max_num_validation(self):
       
  1171 
       
  1172         class ValidationTestInline(TabularInline):
       
  1173             model = ValidationTestInlineModel
       
  1174             max_num = "hello"
       
  1175 
       
  1176         class ValidationTestModelAdmin(ModelAdmin):
       
  1177             inlines = [ValidationTestInline]
       
  1178 
       
  1179         self.assertRaisesErrorWithMessage(
       
  1180             ImproperlyConfigured,
       
  1181             "'ValidationTestInline.max_num' should be an integer or None (default).",
       
  1182             validate,
       
  1183             ValidationTestModelAdmin,
       
  1184             ValidationTestModel,
       
  1185         )
       
  1186 
       
  1187         class ValidationTestInline(TabularInline):
       
  1188             model = ValidationTestInlineModel
       
  1189             max_num = 2
       
  1190 
       
  1191         class ValidationTestModelAdmin(ModelAdmin):
       
  1192             inlines = [ValidationTestInline]
       
  1193 
       
  1194         validate(ValidationTestModelAdmin, ValidationTestModel)
       
  1195 
       
  1196     def test_formset_validation(self):
       
  1197 
       
  1198         class FakeFormSet(object):
       
  1199             pass
       
  1200 
       
  1201         class ValidationTestInline(TabularInline):
       
  1202             model = ValidationTestInlineModel
       
  1203             formset = FakeFormSet
       
  1204 
       
  1205         class ValidationTestModelAdmin(ModelAdmin):
       
  1206             inlines = [ValidationTestInline]
       
  1207 
       
  1208         self.assertRaisesErrorWithMessage(
       
  1209             ImproperlyConfigured,
       
  1210             "'ValidationTestInline.formset' does not inherit from BaseModelFormSet.",
       
  1211             validate,
       
  1212             ValidationTestModelAdmin,
       
  1213             ValidationTestModel,
       
  1214         )
       
  1215 
       
  1216         class RealModelFormSet(BaseModelFormSet):
       
  1217             pass
       
  1218 
       
  1219         class ValidationTestInline(TabularInline):
       
  1220             model = ValidationTestInlineModel
       
  1221             formset = RealModelFormSet
       
  1222 
       
  1223         class ValidationTestModelAdmin(ModelAdmin):
       
  1224             inlines = [ValidationTestInline]
       
  1225 
       
  1226         validate(ValidationTestModelAdmin, ValidationTestModel)