123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- from django import forms
- from django.contrib import admin
- from django.contrib.admin.widgets import AutocompleteSelect
- from django.forms import ModelChoiceField
- from django.test import TestCase, override_settings
- from django.utils import translation
- from .models import Album, Band, ReleaseEvent, VideoStream
- class AlbumForm(forms.ModelForm):
- class Meta:
- model = Album
- fields = ["band", "featuring"]
- widgets = {
- "band": AutocompleteSelect(
- Album._meta.get_field("band"),
- admin.site,
- attrs={"class": "my-class"},
- ),
- "featuring": AutocompleteSelect(
- Album._meta.get_field("featuring"),
- admin.site,
- ),
- }
- class NotRequiredBandForm(forms.Form):
- band = ModelChoiceField(
- queryset=Album.objects.all(),
- widget=AutocompleteSelect(
- Album._meta.get_field("band").remote_field, admin.site
- ),
- required=False,
- )
- class RequiredBandForm(forms.Form):
- band = ModelChoiceField(
- queryset=Album.objects.all(),
- widget=AutocompleteSelect(
- Album._meta.get_field("band").remote_field, admin.site
- ),
- required=True,
- )
- class VideoStreamForm(forms.ModelForm):
- class Meta:
- model = VideoStream
- fields = ["release_event"]
- widgets = {
- "release_event": AutocompleteSelect(
- VideoStream._meta.get_field("release_event"),
- admin.site,
- ),
- }
- @override_settings(ROOT_URLCONF="admin_widgets.urls")
- class AutocompleteMixinTests(TestCase):
- empty_option = '<option value=""></option>'
- maxDiff = 1000
- def test_build_attrs(self):
- form = AlbumForm()
- attrs = form["band"].field.widget.get_context(
- name="my_field", value=None, attrs={}
- )["widget"]["attrs"]
- self.assertEqual(
- attrs,
- {
- "class": "my-class admin-autocomplete",
- "data-ajax--cache": "true",
- "data-ajax--delay": 250,
- "data-ajax--type": "GET",
- "data-ajax--url": "/autocomplete/",
- "data-theme": "admin-autocomplete",
- "data-allow-clear": "false",
- "data-app-label": "admin_widgets",
- "data-field-name": "band",
- "data-model-name": "album",
- "data-placeholder": "",
- "lang": "en",
- },
- )
- def test_build_attrs_no_custom_class(self):
- form = AlbumForm()
- attrs = form["featuring"].field.widget.get_context(
- name="name", value=None, attrs={}
- )["widget"]["attrs"]
- self.assertEqual(attrs["class"], "admin-autocomplete")
- def test_build_attrs_not_required_field(self):
- form = NotRequiredBandForm()
- attrs = form["band"].field.widget.build_attrs({})
- self.assertJSONEqual(attrs["data-allow-clear"], True)
- def test_build_attrs_required_field(self):
- form = RequiredBandForm()
- attrs = form["band"].field.widget.build_attrs({})
- self.assertJSONEqual(attrs["data-allow-clear"], False)
- def test_get_url(self):
- rel = Album._meta.get_field("band")
- w = AutocompleteSelect(rel, admin.site)
- url = w.get_url()
- self.assertEqual(url, "/autocomplete/")
- def test_render_options(self):
- beatles = Band.objects.create(name="The Beatles", style="rock")
- who = Band.objects.create(name="The Who", style="rock")
- # With 'band', a ForeignKey.
- form = AlbumForm(initial={"band": beatles.uuid})
- output = form.as_table()
- selected_option = (
- '<option value="%s" selected>The Beatles</option>' % beatles.uuid
- )
- option = '<option value="%s">The Who</option>' % who.uuid
- self.assertIn(selected_option, output)
- self.assertNotIn(option, output)
- # With 'featuring', a ManyToManyField.
- form = AlbumForm(initial={"featuring": [beatles.pk, who.pk]})
- output = form.as_table()
- selected_option = (
- '<option value="%s" selected>The Beatles</option>' % beatles.pk
- )
- option = '<option value="%s" selected>The Who</option>' % who.pk
- self.assertIn(selected_option, output)
- self.assertIn(option, output)
- def test_render_options_required_field(self):
- """Empty option is present if the field isn't required."""
- form = NotRequiredBandForm()
- output = form.as_table()
- self.assertIn(self.empty_option, output)
- def test_render_options_not_required_field(self):
- """Empty option isn't present if the field isn't required."""
- form = RequiredBandForm()
- output = form.as_table()
- self.assertNotIn(self.empty_option, output)
- def test_render_options_fk_as_pk(self):
- beatles = Band.objects.create(name="The Beatles", style="rock")
- rubber_soul = Album.objects.create(name="Rubber Soul", band=beatles)
- release_event = ReleaseEvent.objects.create(
- name="Test Target", album=rubber_soul
- )
- form = VideoStreamForm(initial={"release_event": release_event.pk})
- output = form.as_table()
- selected_option = (
- '<option value="%s" selected>Test Target</option>' % release_event.pk
- )
- self.assertIn(selected_option, output)
- def test_media(self):
- rel = Album._meta.get_field("band").remote_field
- base_files = (
- "admin/js/vendor/jquery/jquery.min.js",
- "admin/js/vendor/select2/select2.full.min.js",
- # Language file is inserted here.
- "admin/js/jquery.init.js",
- "admin/js/autocomplete.js",
- )
- languages = (
- ("de", "de"),
- # Subsequent language codes are used when the language code is not
- # supported.
- ("de-at", "de"),
- ("de-ch-1901", "de"),
- ("en-latn-us", "en"),
- ("nl-nl-x-informal", "nl"),
- ("zh-hans-HK", "zh-CN"),
- # Language with code 00 does not exist.
- ("00", None),
- # Language files are case sensitive.
- ("sr-cyrl", "sr-Cyrl"),
- ("zh-hans", "zh-CN"),
- ("zh-hant", "zh-TW"),
- )
- for lang, select_lang in languages:
- with self.subTest(lang=lang):
- if select_lang:
- expected_files = (
- base_files[:2]
- + (("admin/js/vendor/select2/i18n/%s.js" % select_lang),)
- + base_files[2:]
- )
- else:
- expected_files = base_files
- with translation.override(lang):
- self.assertEqual(
- AutocompleteSelect(rel, admin.site).media._js,
- list(expected_files),
- )
|