[WIKI-852] chore: update page version save logic (#8440)

* chore: updated the logic for page version task

* chore: updated the html variable

* chore: handled the exception

* chore: changed the function name

* chore: added a custom variable
This commit is contained in:
Bavisetti Narayan 2026-03-03 19:10:42 +05:30 committed by GitHub
parent a9d688f290
commit a58642ed10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 54 additions and 20 deletions

View file

@ -50,7 +50,7 @@ from plane.utils.error_codes import ERROR_CODES
# Local imports # Local imports
from ..base import BaseAPIView, BaseViewSet from ..base import BaseAPIView, BaseViewSet
from plane.bgtasks.page_transaction_task import page_transaction from plane.bgtasks.page_transaction_task import page_transaction
from plane.bgtasks.page_version_task import page_version from plane.bgtasks.page_version_task import track_page_version
from plane.bgtasks.recent_visited_task import recent_visited_task from plane.bgtasks.recent_visited_task import recent_visited_task
from plane.bgtasks.copy_s3_object import copy_s3_objects_of_description_and_assets from plane.bgtasks.copy_s3_object import copy_s3_objects_of_description_and_assets
from plane.app.permissions import ProjectPagePermission from plane.app.permissions import ProjectPagePermission
@ -545,26 +545,28 @@ class PagesDescriptionViewSet(BaseViewSet):
status=status.HTTP_400_BAD_REQUEST, status=status.HTTP_400_BAD_REQUEST,
) )
# Store the old description_html before saving (needed for both tasks)
old_description_html = page.description_html
# Serialize the existing instance # Serialize the existing instance
existing_instance = json.dumps({"description_html": page.description_html}, cls=DjangoJSONEncoder) existing_instance = json.dumps({"description_html": old_description_html}, cls=DjangoJSONEncoder)
# Use serializer for validation and update # Use serializer for validation and update
serializer = PageBinaryUpdateSerializer(page, data=request.data, partial=True) serializer = PageBinaryUpdateSerializer(page, data=request.data, partial=True)
if serializer.is_valid(): if serializer.is_valid():
serializer.save()
# Capture the page transaction # Capture the page transaction
if request.data.get("description_html"): if request.data.get("description_html"):
page_transaction.delay( page_transaction.delay(
new_description_html=request.data.get("description_html", "<p></p>"), new_description_html=request.data.get("description_html", "<p></p>"),
old_description_html=page.description_html, old_description_html=old_description_html,
page_id=page_id, page_id=page_id,
) )
# Update the page using serializer
updated_page = serializer.save()
# Run background tasks # Run background tasks
page_version.delay( track_page_version.delay(
page_id=updated_page.id, page_id=page_id,
existing_instance=existing_instance, existing_instance=existing_instance,
user_id=request.user.id, user_id=request.user.id,
) )

View file

@ -5,37 +5,69 @@
# Python imports # Python imports
import json import json
# Third party imports # Third party imports
from celery import shared_task from celery import shared_task
# Django imports
from django.utils import timezone
# Module imports # Module imports
from plane.db.models import Page, PageVersion from plane.db.models import Page, PageVersion
from plane.utils.exception_logger import log_exception from plane.utils.exception_logger import log_exception
PAGE_VERSION_TASK_TIMEOUT = 600
@shared_task @shared_task
def page_version(page_id, existing_instance, user_id): def track_page_version(page_id, existing_instance, user_id):
try: try:
# Get the page # Get the page
page = Page.objects.get(id=page_id) page = Page.objects.get(id=page_id)
# Get the current instance # Get the current instance
current_instance = json.loads(existing_instance) if existing_instance is not None else {} current_instance = json.loads(existing_instance) if existing_instance is not None else {}
sub_pages = {}
# Create a version if description_html is updated # Create a version if description_html is updated
if current_instance.get("description_html") != page.description_html: if current_instance.get("description_html") != page.description_html:
# Create a new page version # Fetch the latest page version
PageVersion.objects.create( page_version = PageVersion.objects.filter(page_id=page_id).order_by("-last_saved_at").first()
page_id=page_id,
workspace_id=page.workspace_id,
description_html=page.description_html,
description_binary=page.description_binary,
owned_by_id=user_id,
last_saved_at=page.updated_at,
description_json=page.description_json,
description_stripped=page.description_stripped,
)
# Get the latest page version if it exists and is owned by the user
if (
page_version
and str(page_version.owned_by_id) == str(user_id)
and (timezone.now() - page_version.last_saved_at).total_seconds() <= PAGE_VERSION_TASK_TIMEOUT
):
page_version.description_html = page.description_html
page_version.description_binary = page.description_binary
page_version.description_json = page.description
page_version.description_stripped = page.description_stripped
page_version.sub_pages_data = sub_pages
page_version.save(
update_fields=[
"description_html",
"description_binary",
"description_json",
"description_stripped",
"sub_pages_data",
"updated_at"
]
)
else:
# Create a new page version
PageVersion.objects.create(
page_id=page_id,
workspace_id=page.workspace_id,
description_json=page.description,
description_html=page.description_html,
description_binary=page.description_binary,
description_stripped=page.description_stripped,
owned_by_id=user_id,
last_saved_at=timezone.now(),
sub_pages_data=sub_pages,
)
# If page versions are greater than 20 delete the oldest one # If page versions are greater than 20 delete the oldest one
if PageVersion.objects.filter(page_id=page_id).count() > 20: if PageVersion.objects.filter(page_id=page_id).count() > 20:
# Delete the old page version # Delete the old page version