Exclude latest_revision when copying objects for translation

pull/10019/head
Sage Abdullah 2023-01-26 15:27:24 +00:00 zatwierdzone przez Matt Westcott
rodzic 7339f6c3d1
commit 528fd78c76
3 zmienionych plików z 80 dodań i 15 usunięć

Wyświetl plik

@ -2,6 +2,7 @@ from django.core.exceptions import PermissionDenied
from django.db import transaction from django.db import transaction
from wagtail.coreutils import find_available_slug from wagtail.coreutils import find_available_slug
from wagtail.models.copying import _copy
class ParentNotTranslatedError(Exception): class ParentNotTranslatedError(Exception):
@ -13,14 +14,18 @@ class ParentNotTranslatedError(Exception):
pass pass
class CopyPageForTranslationPermissionError(PermissionDenied): class CopyForTranslationPermissionError(PermissionDenied):
""" """
Raised when the page translation copy cannot be performed due to insufficient permissions. Raised when the object translation copy cannot be performed due to insufficient permissions.
""" """
pass pass
class CopyPageForTranslationPermissionError(CopyForTranslationPermissionError):
pass
class CopyPageForTranslationAction: class CopyPageForTranslationAction:
""" """
Creates a copy of this page in the specified locale. Creates a copy of this page in the specified locale.
@ -153,3 +158,64 @@ class CopyPageForTranslationAction:
self.walk(self.page) self.walk(self.page)
return translated_page return translated_page
class CopyForTranslationAction:
"""
Creates a copy of this object in the specified locale.
The ``exclude_fields`` parameter can be used to set any fields to a blank value
in the copy.
"""
def __init__(
self,
object,
locale,
exclude_fields=None,
user=None,
):
self.object = object
self.locale = locale
self.exclude_fields = exclude_fields
self.user = user
def check(self, skip_permission_checks=False):
# Permission checks
if (
self.user
and not skip_permission_checks
and not self.user.has_perms(["simple_translation.submit_translation"])
):
raise CopyForTranslationPermissionError(
"You do not have permission to submit a translation for this object."
)
@transaction.atomic
def _copy_for_translation(self, object, locale, exclude_fields=None):
from wagtail.models import TranslatableMixin
exclude_fields = (
getattr(object, "default_exclude_fields_in_copy", [])
+ getattr(object, "exclude_fields_in_copy", [])
+ (exclude_fields or [])
)
translated, child_object_map = _copy(object, exclude_fields=exclude_fields)
translated.locale = locale
# Update locale on any translatable child objects as well
# Note: If this is not a subclass of ClusterableModel, child_object_map will always be '{}'
for (_child_relation, _old_pk), child_object in child_object_map.items():
if isinstance(child_object, TranslatableMixin):
child_object.locale = locale
return translated
def execute(self, skip_permission_checks=False):
self.check(skip_permission_checks=skip_permission_checks)
translated_object = self._copy_for_translation(
self.object, self.locale, self.exclude_fields
)
return translated_object

Wyświetl plik

@ -234,6 +234,11 @@ class RevisionMixin(models.Model):
editable=False, editable=False,
) )
# An array of additional field names that will not be included when the object is copied.
default_exclude_fields_in_copy = [
"latest_revision",
]
@property @property
def revisions(self): def revisions(self):
""" """

Wyświetl plik

@ -10,14 +10,13 @@ from django.utils import translation
from django.utils.encoding import force_str from django.utils.encoding import force_str
from modelcluster.fields import ParentalKey from modelcluster.fields import ParentalKey
from wagtail.actions.copy_for_translation import CopyForTranslationAction
from wagtail.coreutils import ( from wagtail.coreutils import (
get_content_languages, get_content_languages,
get_supported_content_language_variant, get_supported_content_language_variant,
) )
from wagtail.signals import pre_validate_delete from wagtail.signals import pre_validate_delete
from .copying import _copy
def pk(obj): def pk(obj):
if isinstance(obj, models.Model): if isinstance(obj, models.Model):
@ -205,22 +204,17 @@ class TranslatableMixin(models.Model):
self.get_translations(inclusive=True).filter(locale_id=pk(locale)).exists() self.get_translations(inclusive=True).filter(locale_id=pk(locale)).exists()
) )
def copy_for_translation(self, locale): def copy_for_translation(self, locale, exclude_fields=None):
""" """
Creates a copy of this instance with the specified locale. Creates a copy of this instance with the specified locale.
Note that the copy is initially unsaved. Note that the copy is initially unsaved.
""" """
translated, child_object_map = _copy(self) return CopyForTranslationAction(
translated.locale = locale self,
locale,
# Update locale on any translatable child objects as well exclude_fields=exclude_fields,
# Note: If this is not a subclass of ClusterableModel, child_object_map will always be '{}' ).execute()
for (_child_relation, _old_pk), child_object in child_object_map.items():
if isinstance(child_object, TranslatableMixin):
child_object.locale = locale
return translated
def get_default_locale(self): def get_default_locale(self):
""" """