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('