mirror of
https://github.com/django/django.git
synced 2025-10-23 21:59:11 +00:00
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
This commit is contained in:
112
tests/regressiontests/admin_widgets/tests.py
Normal file
112
tests/regressiontests/admin_widgets/tests.py
Normal file
@@ -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)
|
||||
Reference in New Issue
Block a user