diff options
| author | Jacob Kaplan-Moss <jacob@jacobian.org> | 2009-01-16 15:32:31 +0000 |
|---|---|---|
| committer | Jacob Kaplan-Moss <jacob@jacobian.org> | 2009-01-16 15:32:31 +0000 |
| commit | f212b24b6469b66424354bf970f3051df180b88d (patch) | |
| tree | 379b8102f38ddde424cb0005cf2f468d409f691e /tests/regressiontests/admin_widgets/tests.py | |
| parent | d579e716fef9f06f04861815cf949630d8633271 (diff) | |
Cleaned up and refactored `ModelAdmin.formfield_for_dbfield`:
* The new method uses an admin configuration option (`formfield_overrides`); this makes custom admin widgets especially easy.
* Refactored what was left of `formfield_for_dbfield` into a handful of smaller methods so that it's easier to hook in and return custom fields where needed.
* These `formfield_for_*` methods now pass around `request` so that you can easily modify fields based on request (as in #3987).
Fixes #8306, #3987, #9148.
Thanks to James Bennet for the original patch; Alex Gaynor and Brian Rosner also contributed.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9760 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/regressiontests/admin_widgets/tests.py')
| -rw-r--r-- | tests/regressiontests/admin_widgets/tests.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/tests/regressiontests/admin_widgets/tests.py b/tests/regressiontests/admin_widgets/tests.py new file mode 100644 index 0000000000..2794b3fb80 --- /dev/null +++ b/tests/regressiontests/admin_widgets/tests.py @@ -0,0 +1,112 @@ +from django import forms +from django.contrib import admin +from django.contrib.admin import widgets +from unittest import TestCase +from django.test import TestCase as DjangoTestCase +import models + +class AdminFormfieldForDBFieldTests(TestCase): + """ + Tests for correct behavior of ModelAdmin.formfield_for_dbfield + """ + + def assertFormfield(self, model, fieldname, widgetclass, **admin_overrides): + """ + Helper to call formfield_for_dbfield for a given model and field name + and verify that the returned formfield is appropriate. + """ + # Override any settings on the model admin + class MyModelAdmin(admin.ModelAdmin): pass + for k in admin_overrides: + setattr(MyModelAdmin, k, admin_overrides[k]) + + # Construct the admin, and ask it for a formfield + ma = MyModelAdmin(model, admin.site) + ff = ma.formfield_for_dbfield(model._meta.get_field(fieldname), request=None) + + # "unwrap" the widget wrapper, if needed + if isinstance(ff.widget, widgets.RelatedFieldWidgetWrapper): + widget = ff.widget.widget + else: + widget = ff.widget + + # Check that we got a field of the right type + self.assert_( + isinstance(widget, widgetclass), + "Wrong widget for %s.%s: expected %s, got %s" % \ + (model.__class__.__name__, fieldname, widgetclass, type(widget)) + ) + + # Return the formfield so that other tests can continue + return ff + + def testDateField(self): + self.assertFormfield(models.Event, 'date', widgets.AdminDateWidget) + + def testDateTimeField(self): + self.assertFormfield(models.Member, 'birthdate', widgets.AdminSplitDateTime) + + def testTimeField(self): + self.assertFormfield(models.Event, 'start_time', widgets.AdminTimeWidget) + + def testTextField(self): + self.assertFormfield(models.Event, 'description', widgets.AdminTextareaWidget) + + def testURLField(self): + self.assertFormfield(models.Event, 'link', widgets.AdminURLFieldWidget) + + def testIntegerField(self): + self.assertFormfield(models.Event, 'min_age', widgets.AdminIntegerFieldWidget) + + def testCharField(self): + self.assertFormfield(models.Member, 'name', widgets.AdminTextInputWidget) + + def testFileField(self): + self.assertFormfield(models.Album, 'cover_art', widgets.AdminFileWidget) + + def testForeignKey(self): + self.assertFormfield(models.Event, 'band', forms.Select) + + def testRawIDForeignKey(self): + self.assertFormfield(models.Event, 'band', widgets.ForeignKeyRawIdWidget, + raw_id_fields=['band']) + + def testRadioFieldsForeignKey(self): + ff = self.assertFormfield(models.Event, 'band', widgets.AdminRadioSelect, + radio_fields={'band':admin.VERTICAL}) + self.assertEqual(ff.empty_label, None) + + def testManyToMany(self): + self.assertFormfield(models.Band, 'members', forms.SelectMultiple) + + def testRawIDManyTOMany(self): + self.assertFormfield(models.Band, 'members', widgets.ManyToManyRawIdWidget, + raw_id_fields=['members']) + + def testFilteredManyToMany(self): + self.assertFormfield(models.Band, 'members', widgets.FilteredSelectMultiple, + filter_vertical=['members']) + + def testFormfieldOverrides(self): + self.assertFormfield(models.Event, 'date', forms.TextInput, + formfield_overrides={'widget': forms.TextInput}) + + def testFieldWithChoices(self): + self.assertFormfield(models.Member, 'gender', forms.Select) + + def testChoicesWithRadioFields(self): + self.assertFormfield(models.Member, 'gender', widgets.AdminRadioSelect, + radio_fields={'gender':admin.VERTICAL}) + + +class AdminFormfieldForDBFieldWithRequestTests(DjangoTestCase): + fixtures = ["admin-widgets-users.xml"] + + def testFilterChoicesByRequestUser(self): + """ + Ensure the user can only see their own cars in the foreign key dropdown. + """ + self.client.login(username="super", password="secret") + response = self.client.get("/widget_admin/admin_widgets/cartire/add/") + self.assert_("BMW M3" not in response.content) + self.assert_("Volkswagon Passat" in response.content) |
