diff --git a/localized_fields/templates/localized_fields/admin/widget.html b/localized_fields/templates/localized_fields/admin/widget.html index 2d9152e..2c14e03 100644 --- a/localized_fields/templates/localized_fields/admin/widget.html +++ b/localized_fields/templates/localized_fields/admin/widget.html @@ -1,14 +1,16 @@ +{% with widget_id=widget.attrs.id %}
-{% for key, widget in widgets %} -
- {{ widget }} +{% for widget in widget.subwidgets %} +
+ {% include widget.template_name %}
{% endfor %}
+{% endwith %} diff --git a/localized_fields/widgets.py b/localized_fields/widgets.py index 451a724..9163fcf 100644 --- a/localized_fields/widgets.py +++ b/localized_fields/widgets.py @@ -3,7 +3,6 @@ from typing import List from django.conf import settings from django import forms from django.contrib.admin import widgets -from django.template.loader import render_to_string from .value import LocalizedValue @@ -49,54 +48,37 @@ class LocalizedFieldWidget(forms.MultiWidget): return result - -class LocalizedCharFieldWidget(LocalizedFieldWidget): - """Widget that has an input box for every language.""" - widget = forms.TextInput - - -class LocalizedFileWidget(LocalizedFieldWidget): - """Widget that has an file input box for every language.""" - widget = forms.ClearableFileInput - - -class AdminLocalizedFieldWidget(LocalizedFieldWidget): - widget = widgets.AdminTextareaWidget - template = 'localized_fields/admin/widget.html' - - def render(self, name, value, attrs=None): + def get_context(self, name, value, attrs): + context = super(forms.MultiWidget, self).get_context(name, value, attrs) if self.is_localized: for widget in self.widgets: widget.is_localized = self.is_localized - # value is a list of values, each corresponding to a widget # in self.widgets. if not isinstance(value, list): value = self.decompress(value) - output = [] - final_attrs = self.build_attrs(attrs) + final_attrs = context['widget']['attrs'] + input_type = final_attrs.pop('type', None) id_ = final_attrs.get('id') - + subwidgets = [] for i, widget in enumerate(self.widgets): + if input_type is not None: + widget.input_type = input_type + widget_name = '%s_%s' % (name, i) try: widget_value = value[i] except IndexError: widget_value = None if id_: - final_attrs = dict(final_attrs, id='%s_%s' % (id_, i)) - - widget_attrs = self.build_widget_attrs(widget, widget_value, final_attrs) - output.append(widget.render(name + '_%s' % i, widget_value, widget_attrs)) - - context = { - 'id': final_attrs.get('id'), - 'name': name, - 'widgets': zip([code for code, lang in settings.LANGUAGES], output), - 'available_languages': settings.LANGUAGES - } - - return render_to_string(self.template, context) + widget_attrs = final_attrs.copy() + widget_attrs['id'] = '%s_%s' % (id_, i) + else: + widget_attrs = final_attrs + widget_attrs = self.build_widget_attrs(widget, widget_value, widget_attrs) + subwidgets.append(widget.get_context(widget_name, widget_value, widget_attrs)['widget']) + context['widget']['subwidgets'] = subwidgets + return context @staticmethod def build_widget_attrs(widget, value, attrs): @@ -109,6 +91,21 @@ class AdminLocalizedFieldWidget(LocalizedFieldWidget): return attrs +class LocalizedCharFieldWidget(LocalizedFieldWidget): + """Widget that has an input box for every language.""" + widget = forms.TextInput + + +class LocalizedFileWidget(LocalizedFieldWidget): + """Widget that has an file input box for every language.""" + widget = forms.ClearableFileInput + + +class AdminLocalizedFieldWidget(LocalizedFieldWidget): + template_name = 'localized_fields/admin/widget.html' + widget = widgets.AdminTextareaWidget + + class AdminLocalizedCharFieldWidget(AdminLocalizedFieldWidget): widget = widgets.AdminTextInputWidget diff --git a/tests/test_file_widget.py b/tests/test_file_widget.py new file mode 100644 index 0000000..87404ea --- /dev/null +++ b/tests/test_file_widget.py @@ -0,0 +1,24 @@ +from django.test import TestCase + +from localized_fields.value import LocalizedFileValue +from localized_fields.widgets import LocalizedFileWidget + + +class LocalizedFileWidgetTestCase(TestCase): + """Tests the workings of the :see:LocalizedFiledWidget class.""" + + @staticmethod + def test_get_context(): + """Tests whether the :see:get_context correctly + handles 'required' attribute, separately for each subwidget.""" + + widget = LocalizedFileWidget() + widget.widgets[0].is_required = True + widget.widgets[1].is_required = True + widget.widgets[2].is_required = False + context = widget.get_context(name='test', + value=LocalizedFileValue(dict(en='test')), + attrs=dict(required=True)) + assert 'required' not in context['widget']['subwidgets'][0]['attrs'] + assert context['widget']['subwidgets'][1]['attrs']['required'] + assert 'required' not in context['widget']['subwidgets'][2]['attrs'] diff --git a/tests/test_widget.py b/tests/test_widget.py index f9bd382..192032b 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -44,6 +44,19 @@ class LocalizedFieldWidgetTestCase(TestCase): for _, value in zip(settings.LANGUAGES, decompressed_values): assert not value + @staticmethod + def test_get_context(): + """Tests whether the :see:get_context correctly + handles 'required' attribute, separately for each subwidget.""" + + widget = LocalizedFieldWidget() + widget.widgets[0].is_required = True + widget.widgets[1].is_required = False + context = widget.get_context(name='test', value=LocalizedValue(), + attrs=dict(required=True)) + assert context['widget']['subwidgets'][0]['attrs']['required'] + assert 'required' not in context['widget']['subwidgets'][1]['attrs'] + @staticmethod def test_render(): """Tests whether the :see:LocalizedFieldWidget correctly @@ -52,4 +65,3 @@ class LocalizedFieldWidgetTestCase(TestCase): widget = LocalizedFieldWidget() output = widget.render(name='title', value=None) assert bool(re.search('