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 wagtail.coreutils import find_available_slug
from wagtail.models.copying import _copy
class ParentNotTranslatedError(Exception):
@ -13,14 +14,18 @@ class ParentNotTranslatedError(Exception):
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
class CopyPageForTranslationPermissionError(CopyForTranslationPermissionError):
pass
class CopyPageForTranslationAction:
"""
Creates a copy of this page in the specified locale.
@ -153,3 +158,64 @@ class CopyPageForTranslationAction:
self.walk(self.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,
)
# An array of additional field names that will not be included when the object is copied.
default_exclude_fields_in_copy = [
"latest_revision",
]
@property
def revisions(self):
"""

Wyświetl plik

@ -10,14 +10,13 @@ from django.utils import translation
from django.utils.encoding import force_str
from modelcluster.fields import ParentalKey
from wagtail.actions.copy_for_translation import CopyForTranslationAction
from wagtail.coreutils import (
get_content_languages,
get_supported_content_language_variant,
)
from wagtail.signals import pre_validate_delete
from .copying import _copy
def pk(obj):
if isinstance(obj, models.Model):
@ -205,22 +204,17 @@ class TranslatableMixin(models.Model):
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.
Note that the copy is initially unsaved.
"""
translated, child_object_map = _copy(self)
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
return CopyForTranslationAction(
self,
locale,
exclude_fields=exclude_fields,
).execute()
def get_default_locale(self):
"""