mirror of
https://github.com/SectorLabs/django-localized-fields.git
synced 2025-04-25 03:32:55 +03:00
Merge pull request #34 from MELScience/widget_refactor
Use template-based widget rendering in AdminLocalizedFieldWidget
This commit is contained in:
commit
d5f43c783a
@ -1,14 +1,16 @@
|
|||||||
|
{% with widget_id=widget.attrs.id %}
|
||||||
<div class="localized-fields-widget" role="tabs" data-synctabs="translation">
|
<div class="localized-fields-widget" role="tabs" data-synctabs="translation">
|
||||||
<ul class="localized-fields-widget tabs">
|
<ul class="localized-fields-widget tabs">
|
||||||
{% for key, lang in available_languages %}
|
{% for widget in widget.subwidgets %}
|
||||||
<li class="localized-fields-widget tab">
|
<li class="localized-fields-widget tab">
|
||||||
<a href="#{{ id }}_{{ key }}">{{ lang|capfirst }}</a>
|
<a href="#{{ widget_id }}_{{ widget.attrs.lang_code }}">{{ widget.attrs.lang_name|capfirst }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% for key, widget in widgets %}
|
{% for widget in widget.subwidgets %}
|
||||||
<div role="tabpanel" id="{{ id }}_{{ key }}">
|
<div role="tabpanel" id="{{ widget_id }}_{{ widget.attrs.lang_code }}">
|
||||||
{{ widget }}
|
{% include widget.template_name %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endwith %}
|
||||||
|
@ -3,7 +3,6 @@ from typing import List
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.admin import widgets
|
from django.contrib.admin import widgets
|
||||||
from django.template.loader import render_to_string
|
|
||||||
|
|
||||||
from .value import LocalizedValue
|
from .value import LocalizedValue
|
||||||
|
|
||||||
@ -49,54 +48,37 @@ class LocalizedFieldWidget(forms.MultiWidget):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_context(self, name, value, attrs):
|
||||||
class LocalizedCharFieldWidget(LocalizedFieldWidget):
|
context = super(forms.MultiWidget, self).get_context(name, value, attrs)
|
||||||
"""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):
|
|
||||||
if self.is_localized:
|
if self.is_localized:
|
||||||
for widget in self.widgets:
|
for widget in self.widgets:
|
||||||
widget.is_localized = self.is_localized
|
widget.is_localized = self.is_localized
|
||||||
|
|
||||||
# value is a list of values, each corresponding to a widget
|
# value is a list of values, each corresponding to a widget
|
||||||
# in self.widgets.
|
# in self.widgets.
|
||||||
if not isinstance(value, list):
|
if not isinstance(value, list):
|
||||||
value = self.decompress(value)
|
value = self.decompress(value)
|
||||||
|
|
||||||
output = []
|
final_attrs = context['widget']['attrs']
|
||||||
final_attrs = self.build_attrs(attrs)
|
input_type = final_attrs.pop('type', None)
|
||||||
id_ = final_attrs.get('id')
|
id_ = final_attrs.get('id')
|
||||||
|
subwidgets = []
|
||||||
for i, widget in enumerate(self.widgets):
|
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:
|
try:
|
||||||
widget_value = value[i]
|
widget_value = value[i]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
widget_value = None
|
widget_value = None
|
||||||
if id_:
|
if id_:
|
||||||
final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
|
widget_attrs = final_attrs.copy()
|
||||||
|
widget_attrs['id'] = '%s_%s' % (id_, i)
|
||||||
widget_attrs = self.build_widget_attrs(widget, widget_value, final_attrs)
|
else:
|
||||||
output.append(widget.render(name + '_%s' % i, widget_value, widget_attrs))
|
widget_attrs = final_attrs
|
||||||
|
widget_attrs = self.build_widget_attrs(widget, widget_value, widget_attrs)
|
||||||
context = {
|
subwidgets.append(widget.get_context(widget_name, widget_value, widget_attrs)['widget'])
|
||||||
'id': final_attrs.get('id'),
|
context['widget']['subwidgets'] = subwidgets
|
||||||
'name': name,
|
return context
|
||||||
'widgets': zip([code for code, lang in settings.LANGUAGES], output),
|
|
||||||
'available_languages': settings.LANGUAGES
|
|
||||||
}
|
|
||||||
|
|
||||||
return render_to_string(self.template, context)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build_widget_attrs(widget, value, attrs):
|
def build_widget_attrs(widget, value, attrs):
|
||||||
@ -109,6 +91,21 @@ class AdminLocalizedFieldWidget(LocalizedFieldWidget):
|
|||||||
return attrs
|
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):
|
class AdminLocalizedCharFieldWidget(AdminLocalizedFieldWidget):
|
||||||
widget = widgets.AdminTextInputWidget
|
widget = widgets.AdminTextInputWidget
|
||||||
|
|
||||||
|
24
tests/test_file_widget.py
Normal file
24
tests/test_file_widget.py
Normal file
@ -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']
|
@ -44,6 +44,19 @@ class LocalizedFieldWidgetTestCase(TestCase):
|
|||||||
for _, value in zip(settings.LANGUAGES, decompressed_values):
|
for _, value in zip(settings.LANGUAGES, decompressed_values):
|
||||||
assert not value
|
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
|
@staticmethod
|
||||||
def test_render():
|
def test_render():
|
||||||
"""Tests whether the :see:LocalizedFieldWidget correctly
|
"""Tests whether the :see:LocalizedFieldWidget correctly
|
||||||
@ -52,4 +65,3 @@ class LocalizedFieldWidgetTestCase(TestCase):
|
|||||||
widget = LocalizedFieldWidget()
|
widget = LocalizedFieldWidget()
|
||||||
output = widget.render(name='title', value=None)
|
output = widget.render(name='title', value=None)
|
||||||
assert bool(re.search('<label (.|\n|\t)*>\w+<\/label>', output))
|
assert bool(re.search('<label (.|\n|\t)*>\w+<\/label>', output))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user