[damned-lies] Adapt form customisations to Django 1.11
- From: Claude Paroz <claudep src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [damned-lies] Adapt form customisations to Django 1.11
- Date: Wed, 5 Apr 2017 09:22:52 +0000 (UTC)
commit 58f8fe1c92416e0eea7655755cbf2484fbb27324
Author: Claude Paroz <claude 2xlibre net>
Date: Tue Apr 4 23:35:33 2017 +0200
Adapt form customisations to Django 1.11
README | 7 ++---
requirements.txt | 2 +-
vertimus/forms.py | 65 +++++++++++++++++++++-------------------------
vertimus/tests/tests.py | 51 ++++++++++++++++++++++++-------------
4 files changed, 67 insertions(+), 58 deletions(-)
---
diff --git a/README b/README
index daa6cbd..f9a5767 100644
--- a/README
+++ b/README
@@ -8,7 +8,7 @@ You can find the Data model in the /docs directory.
Requirements
============
-1 - Django > 1.8.X
+1 - Django > 1.11.X
2 - Python 3.4 (minimal)
pillow (python-pillow) for hackergotchi checks.
@@ -17,7 +17,7 @@ Requirements
3 - gettext, intltool, gnome-doc-utils (for stats generation), itstool
4 - [Optional] Django Debug Toolbar
- git clone git://github.com/dcramer/django-debug-toolbar.git
+ git clone git://github.com/jazzband/django-debug-toolbar.git
Define USE_DEBUG_TOOLBAR to True in local_settings.py to use it.
5 - [Optional] python-openid and django-openid-auth (see OpenID support
@@ -25,8 +25,7 @@ Requirements
6 - [Optional] python-pyicu for correct sorting in various languages
-7 - [Optional] translate-toolkit >= 1.9.0-beta2 (--keeptranslations option for
- pogrep) for reduced po files.
+7 - [Optional] translate-toolkit >= 2.0 for reduced po files.
Installing all requirements using pip:
diff --git a/requirements.txt b/requirements.txt
index 3b28c28..eaf5798 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-django>=1.10
+django>=1.11
django-debug-toolbar
markdown
pyicu
diff --git a/vertimus/forms.py b/vertimus/forms.py
index ebcfbd6..839ba2f 100644
--- a/vertimus/forms.py
+++ b/vertimus/forms.py
@@ -5,55 +5,49 @@ from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse
from django.utils.html import format_html
from django.utils.translation import ugettext, ugettext_lazy as _
-from vertimus.models import Action, ActionCI
+from vertimus.models import Action, ActionCI, ActionSeparator
from stats.models import Person
from stats.utils import po_file_stats
-class ActionWidget(forms.Select):
- """ Custom widget to disable the separator option (containing "--------") """
- def render_options(self, selected_choices):
- if selected_choices == ['']:
- selected_choices = []
- options = super().render_options(selected_choices)
- options = options.replace('<option value="">--------</option>',
- '<option disabled="disabled">--------</option>')
- return options
-
-
-class AuthorWidget(forms.Select):
- """ Custom widget to disable people without full name or email """
- def render_options(self, selected_choices):
- output = ["<option value=\"\">--------</option>"]
- field = self.choices.field
- for pers in field.queryset.all():
- val, label = field.prepare_value(pers), field.label_from_instance(pers)
- selected_html = ''
- if label == pers.username:
- selected_html = ' disabled'
- label = ugettext("%(name)s (full name missing)") % {'name': label}
- elif not pers.email:
- selected_html = ' disabled'
- label = ugettext("%(name)s (email missing)") % {'name': label}
- elif val in selected_choices:
- selected_html = ' selected'
- output.append(format_html('<option value="{0}"{1}>{2}</option>',
- val, selected_html, label))
- return '\n'.join(output)
+class DisabledLabel(str):
+ """String subclass to mark some label as disabled."""
+
+
+class DisablableSelect(forms.Select):
+ """Custom widget to allow a Select option to be disabled."""
+ def create_option(self, *args, **kwargs):
+ context = super().create_option(*args, **kwargs)
+ if isinstance(context['label'], DisabledLabel):
+ context['attrs']['disabled'] = True
+ if context['selected']:
+ context['selected'] = False
+ del context['attrs']['selected']
+ return context
+
+
+class AuthorChoiceField(forms.ModelChoiceField):
+ widget = DisablableSelect
+
+ def label_from_instance(self, obj):
+ if str(obj) == obj.username:
+ return DisabledLabel(ugettext("%(name)s (full name missing)") % {'name': obj.username})
+ elif not obj.email:
+ return DisabledLabel(ugettext("%(name)s (email missing)") % {'name': str(obj)})
+ return str(obj)
class ActionForm(forms.Form):
action = forms.ChoiceField(label=_("Action"),
# help_text="Choose an action you want to apply",
choices=(),
- widget=ActionWidget)
+ widget=DisablableSelect)
comment = forms.CharField(label=_("Comment"),
# help_text="Leave a comment to explain your action",
max_length=5000,
required=False,
widget=forms.Textarea(attrs={'rows':8, 'cols':70}))
- author = forms.ModelChoiceField(label=_("Commit author"), empty_label=None,
- queryset=Person.objects.none(), widget=AuthorWidget, required=False)
+ author = AuthorChoiceField(label=_("Commit author"), queryset=Person.objects.none(), required=False)
sync_master = forms.BooleanField(
label=_("Sync with master"),
help_text=_("Try to cherry-pick the commit to the master branch"),
@@ -65,9 +59,10 @@ class ActionForm(forms.Form):
def __init__(self, state, actions, has_mailing_list, *args, **kwargs):
super().__init__(*args, **kwargs)
self.actions = actions
- self.fields['action'].choices = [
- (act.name, act.description) for act in actions
- ]
+ self.fields['action'].choices = [(
+ act.name,
+ DisabledLabel(act.description) if isinstance(act, ActionSeparator) else act.description
+ ) for act in actions]
self.fields['action'].help_link = reverse('help', args=['vertimus_workflow', 1])
if state and ActionCI in map(type, self.actions):
self.fields['author'].queryset = state.involved_persons()
diff --git a/vertimus/tests/tests.py b/vertimus/tests/tests.py
index 3c10b19..4ef6964 100644
--- a/vertimus/tests/tests.py
+++ b/vertimus/tests/tests.py
@@ -214,6 +214,29 @@ class VertimusTest(TeamsAndRolesTests):
action_names = [a.name for a in state.get_available_actions(p)]
self.assertEqual(action_names, ['AA', 'WC', None, 'IC', 'AA'])
+ def test_action_menu(self):
+ state = StateNone(branch=self.b, domain=self.d, language=self.l)
+ state.save()
+ form = ActionForm(state, state.get_available_actions(self.pt), False)
+ self.assertHTMLEqual(
+ str(form['action']),
+ '<select id="id_action" name="action">'
+ '<option value="RT">Reserve for translation</option>'
+ '<option value="WC">Write a comment</option>'
+ '</select>'
+ )
+ form = ActionForm(state, state.get_available_actions(self.pcoo), False)
+ self.assertHTMLEqual(
+ str(form['action']),
+ '<select id="id_action" name="action">'
+ '<option value="RT">Reserve for translation</option>'
+ '<option value="WC">Write a comment</option>'
+ '<option value="" disabled>--------</option>'
+ '<option value="IC">Inform of submission</option>'
+ '<option value="AA">Archive the actions</option>'
+ '</select>'
+ )
+
def test_action_wc(self):
state = StateNone(branch=self.b, domain=self.d, language=self.l)
state.save()
@@ -370,25 +393,17 @@ class VertimusTest(TeamsAndRolesTests):
self.assertIn(ActionCI, map(type, state.get_available_actions(self.pcoo)))
form = ActionForm(state, state.get_available_actions(self.pcoo), True)
- self.assertEqual(len(form.fields['author'].choices), 4)
- choices = list(form.fields['author'].choices)
- self.assertEqual(
- [choices[0][1], choices[1][1]],
- ['John Reviewer', 'John Translator']
- )
+ self.assertEqual(len(form.fields['author'].choices), 5)
self.assertEqual(form.fields['author'].initial, self.pr)
- rendered_form = form.as_p()
- self.assertIn(
- '<option value="%d" disabled>ûsername (full name missing)</option>' % pers_no_full_name.pk,
- rendered_form
- )
- self.assertIn(
- '<option value="%d" disabled>Sven Brkc (email missing)</option>' % pers_no_email.pk,
- rendered_form
- )
- self.assertIn(
- '<option value="%d">John Translator</option>' % self.pt.pk,
- rendered_form
+ self.assertHTMLEqual(
+ str(form['author']),
+ '<select id="id_author" name="author">'
+ '<option value="">---------</option>'
+ '<option selected value="%d">John Reviewer</option>'
+ '<option value="%d">John Translator</option>'
+ '<option disabled value="%d">Sven Brkc (email missing)</option>'
+ '<option disabled value="%d">ûsername (full name missing)</option>'
+ '</select>' % (self.pr.pk, self.pt.pk, pers_no_email.pk, pers_no_full_name.pk)
)
def test_action_ci_no_fullname(self):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]