Repository: digitalfabrik/integreat-cms

Issue:
PageTranslations: Revisions
We need a versioning mechanism for page translations. When changing a page, we should not change the content of the page translation instance, but create a new object with a new version number.
For each page and language, only the page translation with the highest version number should be delivered by the API. In case the highest version number has "draft" or "review required" as status, we take the highest version number which is "finished review".

This is part of #104.


Discussion:

Resolving patch:
diff --git a/backend/cms/models/page.py b/backend/cms/models/page.py
--- a/backend/cms/models/page.py
+++ b/backend/cms/models/page.py
@@ -66,7 +66,8 @@ def languages(self):
 
     def get_translation(self, language_code):
         try:
-            page_translation = self.page_translations.get(language__code=language_code)
+            page_translation = self.page_translations.filter(
+                language__code=language_code).order_by('-version').first()
         except ObjectDoesNotExist:
             page_translation = None
         return page_translation
diff --git a/backend/cms/views/pages/page.py b/backend/cms/views/pages/page.py
--- a/backend/cms/views/pages/page.py
+++ b/backend/cms/views/pages/page.py
@@ -49,7 +49,7 @@ def get(self, request, *args, **kwargs):
         page_translation = PageTranslation.objects.filter(
             page=page,
             language=language,
-        ).first()
+        ).order_by('-version').first()
 
         page_form = PageForm(
             instance=page,
@@ -79,7 +79,7 @@ def post(self, request, *args, **kwargs):
         page_translation_instance = PageTranslation.objects.filter(
             page=page_instance,
             language=language,
-        ).first()
+        ).order_by('-version').first()
 
         if not request.user.has_perm('cms.edit_page', page_instance):
             raise PermissionDenied
diff --git a/backend/cms/views/pages/page_form.py b/backend/cms/views/pages/page_form.py
--- a/backend/cms/views/pages/page_form.py
+++ b/backend/cms/views/pages/page_form.py
@@ -199,7 +199,6 @@ def __init__(self, *args, **kwargs):
 
     # pylint: disable=W0221
     def save(self, *args, **kwargs):
-
         logger.info(
             'PageTranslationForm saved with args %s and kwargs %s',
             args,
@@ -210,10 +209,7 @@ def save(self, *args, **kwargs):
         page = kwargs.pop('page', None)
         user = kwargs.pop('user', None)
 
-        if not self.instance.id:
-            # don't commit saving of ModelForm, because required fields are still missing
-            kwargs['commit'] = False
-
+        kwargs['commit'] = False  # Don't save yet. We just want the object.
         page_translation = super(PageTranslationForm, self).save(*args, **kwargs)
 
         if not self.instance.id:
@@ -222,9 +218,13 @@ def save(self, *args, **kwargs):
             page_translation.creator = user
             page_translation.language = self.language
 
-        page_translation.save()
+        page_translation.version = page_translation.version + 1
+        page_translation.save(force_insert=True)
 
         return page_translation
 
     def clean_slug(self):
+        existing_version = PageTranslation.objects.filter(language=self.language, page=self.instance.page)
+        if existing_version:
+            return existing_version.first().slug
         return generate_unique_slug(self, 'page')


Test patch: