Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: perform comment soft_deletion #99

Merged
merged 4 commits into from
Dec 14, 2024
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
2 changes: 1 addition & 1 deletion backend/apps/comment/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

@admin.register(CommentModel)
class CommentAdmin(admin.ModelAdmin):
list_display = ('quibbler', 'content', 'created_at')
list_display = ('quibbler', 'content', 'created_at', 'deleted')
search_fields = ('quibbler__username', 'content')
4 changes: 2 additions & 2 deletions backend/apps/comment/api/v1/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from rest_framework import routers

from .viewsets import CommentViewSet
from .viewsets import CommentModelViewSet

router = routers.DefaultRouter()
router.register(r'', CommentViewSet)
router.register(r'', CommentModelViewSet)

urlpatterns = router.urls
7 changes: 6 additions & 1 deletion backend/apps/comment/api/v1/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
from .serializers import CommentSerializer


class CommentViewSet(viewsets.ModelViewSet):
class CommentModelViewSet(viewsets.ModelViewSet):
queryset = CommentModel.objects.all()
serializer_class = CommentSerializer

def perform_destroy(self, instance):
CommentModel.objects.soft_delete(instance) # pyright: ignore
# perform cleanup
CommentModel.objects.clean_up_soft_deleted() # pyright: ignore
20 changes: 20 additions & 0 deletions backend/apps/comment/managers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.db import models


class CommentManager(models.Manager):
def soft_delete(self, instance):
# if no children- hard delete
if instance.children_count == 0:
instance.delete()
# else- soft delete
else:
instance.deleted = True
instance.content = "[deleted]"
instance.quibbler = None
instance.save()

def clean_up_soft_deleted(self):
# cleanup all comment instances with no children
for comment_instance in self.filter(deleted=True):
if comment_instance.children_count == 0:
comment_instance.delete()
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 5.1.4 on 2024-12-14 10:10

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('comment', '0002_initial'),
('user', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='commentmodel',
name='deleted',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='commentmodel',
name='quibbler',
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to='user.profilemodel',
verbose_name='quibbler',
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 5.1.4 on 2024-12-14 10:51

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('comment', '0003_commentmodel_deleted_alter_commentmodel_quibbler'),
('user', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='commentmodel',
name='downvotes',
field=models.ManyToManyField(
blank=True,
related_name='downvoted_comments',
to='user.profilemodel',
verbose_name='downvotes',
),
),
migrations.AlterField(
model_name='commentmodel',
name='upvotes',
field=models.ManyToManyField(
blank=True,
related_name='upvoted_comments',
to='user.profilemodel',
verbose_name='upvotes',
),
),
]
17 changes: 13 additions & 4 deletions backend/apps/comment/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,36 @@
from apps.user.models import ProfileModel
from common.mixins.model_mixins import CreatedAtMixin

from .managers import CommentManager

# Create your models here.


class CommentModel(CreatedAtMixin, TreeModel):
quibbler = models.ForeignKey(
ProfileModel, on_delete=models.CASCADE, verbose_name=_('quibbler')
ProfileModel, on_delete=models.SET_NULL, null=True, verbose_name=_('quibbler')
)
content = models.TextField(_('content'))
upvotes = models.ManyToManyField(
ProfileModel, related_name='upvotes', blank=True, verbose_name=_('upvotes')
ProfileModel, related_name='upvoted_comments', blank=True, verbose_name=_('upvotes')
)
downvotes = models.ManyToManyField(
ProfileModel, related_name='downvotes', blank=True, verbose_name=_('downvotes')
ProfileModel,
related_name='downvoted_comments',
blank=True,
verbose_name=_('downvotes'),
)
# flag
deleted = models.BooleanField(default=False)
# custom manager for soft-deletions handling
objects = CommentManager()

@property
def children_count(self):
return self.children().count()

def __str__(self) -> str:
return f"Comment by {self.quibbler.username}"
return f"Comment by {self.quibbler}"

class Meta: # pyright: ignore
indexes = [idx.GistIndex(fields=['path'])]
Expand Down
4 changes: 2 additions & 2 deletions backend/apps/quib/api/v1/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from rest_framework.routers import DefaultRouter

from .viewsets import QuibViewSet
from .viewsets import QuibModelViewSet

router = DefaultRouter()
router.register(r'', QuibViewSet)
router.register(r'', QuibModelViewSet)

urlpatterns = router.urls
2 changes: 1 addition & 1 deletion backend/apps/quib/api/v1/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .serializers import QuibSerializer, QuibSlimSerializer


class QuibViewSet(viewsets.ModelViewSet):
class QuibModelViewSet(viewsets.ModelViewSet):
queryset = QuibModel.objects.all()

def get_serializer_class(self): # pyright: ignore
Expand Down
4 changes: 2 additions & 2 deletions backend/apps/quiblet/api/v1/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from rest_framework.routers import DefaultRouter

from .viewsets import QuibletViewSet
from .viewsets import QuibletModelViewSet

router = DefaultRouter()
router.register(r'', QuibletViewSet)
router.register(r'', QuibletModelViewSet)

urlpatterns = router.urls
2 changes: 1 addition & 1 deletion backend/apps/quiblet/api/v1/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from .serializers import QuibletSerializer


class QuibletViewSet(ModelViewSet):
class QuibletModelViewSet(ModelViewSet):
queryset = QuibletModel.objects.all()
serializer_class = QuibletSerializer

Expand Down
6 changes: 3 additions & 3 deletions backend/apps/user/api/v1/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
from rest_framework.routers import DefaultRouter

from .views import LoginAPIView, LogoutAPIView, MeAPIView, RegisterAPIView
from .viewsets import MyProfilesViewSet, ProfileViewSet
from .viewsets import MyProfilesModelViewSet, ProfileModelReadOnlyViewSet

router = DefaultRouter()
router.register(r'profiles', ProfileViewSet)
router.register(r'me/profiles', MyProfilesViewSet, basename='me-profile')
router.register(r'profiles', ProfileModelReadOnlyViewSet)
router.register(r'me/profiles', MyProfilesModelViewSet, basename='me-profile')

urlpatterns = [
# auth endpoints
Expand Down
4 changes: 2 additions & 2 deletions backend/apps/user/api/v1/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .serializers import ProfileSerializer


class ProfileViewSet(viewsets.ReadOnlyModelViewSet):
class ProfileModelReadOnlyViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for performing read-only operations on the Profile model.

Expand All @@ -19,7 +19,7 @@ class ProfileViewSet(viewsets.ReadOnlyModelViewSet):
search_fields = ('username',)


class MyProfilesViewSet(viewsets.ModelViewSet):
class MyProfilesModelViewSet(viewsets.ModelViewSet):
"""
ViewSet to manage profiles associated with the authenticated user.

Expand Down
Empty file added backend/locale/.gitkeep
Empty file.
139 changes: 0 additions & 139 deletions backend/locale/en/LC_MESSAGES/django.po

This file was deleted.

Loading