diff options
| author | Johannes Hoppe <info@johanneshoppe.com> | 2017-05-10 14:48:57 +0200 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-09-18 13:48:02 -0400 |
| commit | 94cd8efc50c717cd00244f4b2233f971a53b205e (patch) | |
| tree | ab1f13a12121907a561962181eaceeab793cb838 /tests/modeladmin | |
| parent | 01a294f8f014a32e288958701540ea47dcb9fc14 (diff) | |
Fixed #14370 -- Allowed using a Select2 widget for ForeignKey and ManyToManyField in the admin.
Thanks Florian Apolloner and Tim Graham for review and
contributing to the patch.
Diffstat (limited to 'tests/modeladmin')
| -rw-r--r-- | tests/modeladmin/models.py | 9 | ||||
| -rw-r--r-- | tests/modeladmin/test_checks.py | 100 | ||||
| -rw-r--r-- | tests/modeladmin/tests.py | 32 |
3 files changed, 134 insertions, 7 deletions
diff --git a/tests/modeladmin/models.py b/tests/modeladmin/models.py index 861a2dbb9d..c0d3c772c9 100644 --- a/tests/modeladmin/models.py +++ b/tests/modeladmin/models.py @@ -14,6 +14,15 @@ class Band(models.Model): return self.name +class Song(models.Model): + name = models.CharField(max_length=100) + band = models.ForeignKey(Band, models.CASCADE) + featuring = models.ManyToManyField(Band, related_name='featured') + + def __str__(self): + return self.name + + class Concert(models.Model): main_band = models.ForeignKey(Band, models.CASCADE, related_name='main_concerts') opening_band = models.ForeignKey(Band, models.CASCADE, related_name='opening_concerts', blank=True) diff --git a/tests/modeladmin/test_checks.py b/tests/modeladmin/test_checks.py index acca6b18a2..eaca153bd8 100644 --- a/tests/modeladmin/test_checks.py +++ b/tests/modeladmin/test_checks.py @@ -6,14 +6,16 @@ from django.core.checks import Error from django.forms.models import BaseModelFormSet from django.test import SimpleTestCase -from .models import Band, ValidationTestInlineModel, ValidationTestModel +from .models import Band, Song, ValidationTestInlineModel, ValidationTestModel class CheckTestCase(SimpleTestCase): - def assertIsInvalid(self, model_admin, model, msg, id=None, hint=None, invalid_obj=None): + def assertIsInvalid(self, model_admin, model, msg, id=None, hint=None, invalid_obj=None, admin_site=None): + if admin_site is None: + admin_site = AdminSite() invalid_obj = invalid_obj or model_admin - admin_obj = model_admin(model, AdminSite()) + admin_obj = model_admin(model, admin_site) self.assertEqual(admin_obj.check(), [Error(msg, hint=hint, obj=invalid_obj, id=id)]) def assertIsInvalidRegexp(self, model_admin, model, msg, id=None, hint=None, invalid_obj=None): @@ -30,8 +32,10 @@ class CheckTestCase(SimpleTestCase): self.assertEqual(error.id, id) self.assertRegex(error.msg, msg) - def assertIsValid(self, model_admin, model): - admin_obj = model_admin(model, AdminSite()) + def assertIsValid(self, model_admin, model, admin_site=None): + if admin_site is None: + admin_site = AdminSite() + admin_obj = model_admin(model, admin_site) self.assertEqual(admin_obj.check(), []) @@ -1153,3 +1157,89 @@ class ListDisplayEditableTests(CheckTestCase): "'list_display_links'.", id='admin.E123', ) + + +class AutocompleteFieldsTests(CheckTestCase): + def test_autocomplete_e036(self): + class Admin(ModelAdmin): + autocomplete_fields = 'name' + + self.assertIsInvalid( + Admin, Band, + msg="The value of 'autocomplete_fields' must be a list or tuple.", + id='admin.E036', + invalid_obj=Admin, + ) + + def test_autocomplete_e037(self): + class Admin(ModelAdmin): + autocomplete_fields = ('nonexistent',) + + self.assertIsInvalid( + Admin, ValidationTestModel, + msg=( + "The value of 'autocomplete_fields[0]' refers to 'nonexistent', " + "which is not an attribute of 'modeladmin.ValidationTestModel'." + ), + id='admin.E037', + invalid_obj=Admin, + ) + + def test_autocomplete_e38(self): + class Admin(ModelAdmin): + autocomplete_fields = ('name',) + + self.assertIsInvalid( + Admin, ValidationTestModel, + msg=( + "The value of 'autocomplete_fields[0]' must be a foreign " + "key or a many-to-many field." + ), + id='admin.E038', + invalid_obj=Admin, + ) + + def test_autocomplete_e039(self): + class Admin(ModelAdmin): + autocomplete_fields = ('band',) + + self.assertIsInvalid( + Admin, Song, + msg=( + 'An admin for model "Band" has to be registered ' + 'to be referenced by Admin.autocomplete_fields.' + ), + id='admin.E039', + invalid_obj=Admin, + ) + + def test_autocomplete_e040(self): + class NoSearchFieldsAdmin(ModelAdmin): + pass + + class AutocompleteAdmin(ModelAdmin): + autocomplete_fields = ('featuring',) + + site = AdminSite() + site.register(Band, NoSearchFieldsAdmin) + self.assertIsInvalid( + AutocompleteAdmin, Song, + msg=( + 'NoSearchFieldsAdmin must define "search_fields", because ' + 'it\'s referenced by AutocompleteAdmin.autocomplete_fields.' + ), + id='admin.E040', + invalid_obj=AutocompleteAdmin, + admin_site=site, + ) + + def test_autocomplete_is_valid(self): + class SearchFieldsAdmin(ModelAdmin): + search_fields = 'name' + + class AutocompleteAdmin(ModelAdmin): + autocomplete_fields = ('featuring',) + + site = AdminSite() + site.register(Band, SearchFieldsAdmin) + self.assertIsValid(AutocompleteAdmin, Song, admin_site=site) diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py index 25b9dfed69..67bed3d697 100644 --- a/tests/modeladmin/tests.py +++ b/tests/modeladmin/tests.py @@ -7,14 +7,17 @@ from django.contrib.admin.options import ( get_content_type_for_model, ) from django.contrib.admin.sites import AdminSite -from django.contrib.admin.widgets import AdminDateWidget, AdminRadioSelect +from django.contrib.admin.widgets import ( + AdminDateWidget, AdminRadioSelect, AutocompleteSelect, + AutocompleteSelectMultiple, +) from django.contrib.auth.models import User from django.db import models from django.forms.widgets import Select from django.test import SimpleTestCase, TestCase from django.test.utils import isolate_apps -from .models import Band, Concert +from .models import Band, Concert, Song class MockRequest: @@ -638,6 +641,31 @@ class ModelAdminTests(TestCase): self.assertEqual(fetched.change_message, str(message)) self.assertEqual(fetched.object_repr, str(self.band)) + def test_get_autocomplete_fields(self): + class NameAdmin(ModelAdmin): + search_fields = ['name'] + + class SongAdmin(ModelAdmin): + autocomplete_fields = ['featuring'] + fields = ['featuring', 'band'] + + class OtherSongAdmin(SongAdmin): + def get_autocomplete_fields(self, request): + return ['band'] + + self.site.register(Band, NameAdmin) + try: + # Uses autocomplete_fields if not overridden. + model_admin = SongAdmin(Song, self.site) + form = model_admin.get_form(request)() + self.assertIsInstance(form.fields['featuring'].widget.widget, AutocompleteSelectMultiple) + # Uses overridden get_autocomplete_fields + model_admin = OtherSongAdmin(Song, self.site) + form = model_admin.get_form(request)() + self.assertIsInstance(form.fields['band'].widget.widget, AutocompleteSelect) + finally: + self.site.unregister(Band) + class ModelAdminPermissionTests(SimpleTestCase): |
