Repository: liqd/a4-opin

Issue:
Organisation form doesn't allow to delete languages
This feature requires parler to release a new version with the <model>.delete_translation method.



Discussion:
https://github.com/django-parler/django-parler/blob/v1.7/parler/models.py

There it is!

Resolving patch:
diff --git a/euth/dashboard/forms.py b/euth/dashboard/forms.py
--- a/euth/dashboard/forms.py
+++ b/euth/dashboard/forms.py
@@ -1,6 +1,7 @@
 import collections
 import re
 
+import parler
 from django import forms
 from django.conf import settings
 from django.core.exceptions import ValidationError
@@ -410,18 +411,19 @@ class OrganisationForm(forms.ModelForm):
     Special form that allows editing of all translated fields.
     """
 
-    translated_fields = [('title', forms.CharField(
-        help_text=_(
-            'The title of '
-            'your organisation'))),
-        ('description_why', forms.CharField(
-            widget=forms.Textarea)),
-        ('description_how', forms.CharField(
-            widget=forms.Textarea)),
-        ('description', forms.CharField(
-            widget=forms.Textarea, help_text=_(
+    translated_fields = [
+        ('title', forms.CharField, {
+            'help_text': _('The title of your organisation')
+        }),
+        ('description_why', forms.CharField, {'widget': forms.Textarea}),
+        ('description_how', forms.CharField, {'widget': forms.Textarea}),
+        ('description', forms.CharField, {
+            'widget': forms.Textarea,
+            'help_text': _(
                 'More info about the organisation / '
-                'Short text for organisation overview')))]
+                'Short text for organisation overview')
+        })
+    ]
     languages = [lang_code for lang_code, lang in settings.LANGUAGES]
 
     class Meta:
@@ -439,16 +441,23 @@ def __init__(self, *args, **kwargs):
 
         # inject additional form fields for translated model fields
         for lang_code in self.languages:
-            for name, translated_field in self.translated_fields:
+            for name, field_cls, kwargs in self.translated_fields:
                 self.instance.set_current_language(lang_code)
+                translated_field = field_cls(**kwargs)
                 label = name.replace('_', ' ').capitalize()
                 identifier = self._get_identifier(
                     lang_code, name)
-                initial = self.instance.safe_translation_getter(
-                    name)
+
                 field = translated_field
                 field.label = label
                 field.required = False
+
+                try:
+                    translation = self.instance.get_translation(lang_code)
+                    initial = getattr(translation, name)
+                except parler.models.TranslationDoesNotExist:
+                    initial = ''
+
                 field.initial = initial
                 self.fields[identifier] = field
 
@@ -489,11 +498,13 @@ def save(self, commit=True):
             for lang_code in self.languages:
                 if lang_code in self.data:
                     instance.set_current_language(lang_code)
-                    for fieldname in self.translated_fields:
-                        identifier = '{}__{}'.format(lang_code, fieldname[0])
-                        setattr(instance, fieldname[0],
+                    for fieldname, _cls, _kwargs in self.translated_fields:
+                        identifier = '{}__{}'.format(lang_code, fieldname)
+                        setattr(instance, fieldname,
                                 self.cleaned_data.get(identifier))
                     instance.save()
+                elif instance.has_translation(lang_code):
+                    instance.delete_translation(lang_code)
         return instance
 
     def clean(self):


Test patch:
diff --git a/tests/dashboard/test_dashboard_views.py b/tests/dashboard/test_dashboard_views.py
--- a/tests/dashboard/test_dashboard_views.py
+++ b/tests/dashboard/test_dashboard_views.py
@@ -345,6 +345,11 @@ def test_dashboard_update_organisation(client, organisation):
         'twitter_handle': 'a thandle',
         'place': 'Berlin',
         'country': 'DE',
+        'en': 'en',
+        'en__title': 'title.en',
+        'en__description': 'desc.en',
+        'en__description_why': 'desc why.en',
+        'en__description_how': 'desc how.en',
         'de': 'de',
         'de__title': 'title.de',
         'de__description': 'desc.de',
@@ -354,13 +359,55 @@ def test_dashboard_update_organisation(client, organisation):
     response.status_code == 200
 
     organisation.refresh_from_db()
+    organisation.get_translation('en').refresh_from_db()
     assert organisation.place == 'Berlin'
     assert organisation.twitter_handle == 'a thandle'
+    assert organisation.description == 'desc.en'
 
     with switch_language(organisation, 'de'):
         assert organisation.description == 'desc.de'
 
 
+@pytest.mark.django_db
+def test_dashboard_organisation_delete_language(client, organisation):
+    url = reverse('dashboard-organisation-edit', kwargs={
+        'organisation_slug': organisation.slug,
+    })
+
+    initiator = organisation.initiators.first()
+    client.login(username=initiator.email, password='password')
+
+    with switch_language(organisation, 'de'):
+        organisation.description = 'desc.de'
+        organisation.description_why = 'desc why.de'
+        organisation.description_how = 'desc how.de'
+        organisation.save()
+
+    response = client.post(url, {
+        'twitter_handle': 'a thandle',
+        'place': 'Berlin',
+        'country': 'DE',
+        'en': 'en',
+        'en__title': 'title.en',
+        'en__description': 'desc.en',
+        'en__description_why': 'desc why.en',
+        'en__description_how': 'desc how.en',
+        'de__title': 'title.de',
+        'de__description': 'desc.de',
+        'de__description_why': 'desc why.de',
+        'de__description_how': 'desc how.de',
+    })
+    response.status_code == 200
+
+    organisation.refresh_from_db()
+    organisation.get_translation('en').refresh_from_db()
+    with switch_language(organisation, 'de'):
+        organisation.description = 'desc.en'
+        organisation.description_why = 'desc why.en'
+        organisation.description_how = 'desc how.en'
+        organisation.save()
+
+
 @pytest.mark.django_db
 def test_dashboard_blueprint(client, organisation):
     from euth.dashboard.blueprints import blueprints