Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions apps/organization/serializers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from common.apps.upload_file.service import get_presigned_url
from common.celery import constants
from common.celery.task_senders import send_task
from django.conf import settings

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Import transaction from django.db to enable executing the S3 deletion task only after the database transaction successfully commits.

Suggested change
from django.conf import settings
from django.conf import settings
from django.db import transaction

from rest_framework import serializers

from apps.organization.models import Organization
Expand All @@ -21,3 +25,26 @@ def validate_slug_name(self, data):
if "_" in data:
raise serializers.ValidationError(detail="slug name is invalid")
return data

def update(self, instance, validated_data):
old_logo = instance.logo
new_logo = validated_data.get("logo", old_logo)
instance = super().update(instance, validated_data)
if old_logo and old_logo != new_logo:
send_task(
name=constants.CONSOLE_SERVICE_DELETE_UPLOAD_FILE,
message={
"bucket_name": settings.AWS_S3.get("AWS_STORAGE_BUCKET_NAME"),
"link_file": f"uploads/{old_logo}",
},
)
Comment on lines +33 to +40

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

To prevent S3 files from being deleted when a database transaction is rolled back (e.g., due to subsequent errors in the request), trigger the Celery task using transaction.on_commit.

Suggested change
if old_logo and old_logo != new_logo:
send_task(
name=constants.CONSOLE_SERVICE_DELETE_UPLOAD_FILE,
message={
"bucket_name": settings.AWS_S3.get("AWS_STORAGE_BUCKET_NAME"),
"link_file": f"uploads/{old_logo}",
},
)
if old_logo and old_logo != new_logo:
transaction.on_commit(
lambda: send_task(
name=constants.CONSOLE_SERVICE_DELETE_UPLOAD_FILE,
message={
"bucket_name": settings.AWS_S3.get("AWS_STORAGE_BUCKET_NAME"),
"link_file": f"uploads/{old_logo}",
},
)
)

return instance

def to_representation(self, instance):
data = super().to_representation(instance)
if instance.logo and instance.logo not in ["", None]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Simplify the truthiness check for instance.logo. In Python, empty strings and None are already falsy, so if instance.logo: is more idiomatic and adheres to PEP 8 programming recommendations.

Suggested change
if instance.logo and instance.logo not in ["", None]:
if instance.logo:
References
  1. PEP 8 recommends using the fact that empty sequences/strings are false, rather than comparing them explicitly. (link)

data["url_logo"] = get_presigned_url(
settings.AWS_S3.get("AWS_STORAGE_BUCKET_NAME"),
f"uploads/{instance.logo}",
)
return data
1 change: 1 addition & 0 deletions bootstrap_service/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

TASKS_CONSOLE = [
constants.CONSOLE_SERVICE_ADD_OR_REMOVE_SPACE,
constants.CONSOLE_SERVICE_DELETE_UPLOAD_FILE,
]

existing = {queue.name: queue for queue in (app.conf.task_queues or ())}
Expand Down
Loading