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