Skip to content

Commit

Permalink
feat(calendar): add model, viewset, serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
Qndndn committed Nov 2, 2023
1 parent f38e059 commit 6f70bec
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 0 deletions.
Empty file added apps/calendar/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions apps/calendar/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions apps/calendar/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class CalendarConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "Calendar"
Empty file.
33 changes: 33 additions & 0 deletions apps/calendar/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from django.db import models

from ara.db.models import MetaDataModel


class Calendar(MetaDataModel):
tag = models.ForeignKey(
verbose_name="태그",
to="core.Tag",
on_delete=models.CASCADE,
related_name="event_set",
db_index=True,
)
is_allday = models.BooleanField(
verbose_name="하루종일",
default=False,
)
start_at = models.DateTimeField(
verbose_name="시작 시간",
blank=True,
null=True,
default=None,
)
end_at = models.DateTimeField(
verbose_name="종료 시간",
blank=True,
null=True,
default=None,
)
title = models.CharField(
verbose_name="제목",
max_length=512,
)
Empty file.
93 changes: 93 additions & 0 deletions apps/calendar/serializers/calendar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from Calendar.models import Calendar
from rest_framework import serializers


class CalendarSerializer(serializers.ModelSerializer):
class Meta:
model = Calendar
fields = "__all__"


from dateutil.relativedelta import relativedelta
from django.utils import timezone
from django.utils.translation import gettext
from rest_framework import serializers

from apps.user.models import UserProfile
from ara.classes.serializers import MetaDataModelSerializer


class UserProfileSerializer(MetaDataModelSerializer):
...


class UserProfileUpdateActionSerializer(MetaDataModelSerializer):
class Meta(MetaDataModelSerializer.Meta):
read_only_fields = (
"sid",
"user",
)

def validate_nickname(self, value) -> str:
nickname_changed = self.instance and value != self.instance.nickname
if nickname_changed and not self.instance.can_change_nickname():
next_change_date = self.instance.nickname_updated_at + relativedelta(
months=3
)
raise serializers.ValidationError(
gettext(
"Nicknames can only be changed every 3 months. (can't change until %(date)s)"
)
% {"date": next_change_date.strftime("%Y/%m/%d")}
)
return value

def update(self, instance, validated_data):
new_nickname = validated_data.get("nickname")
old_nickname = instance.nickname if instance else None
if instance and new_nickname and old_nickname != new_nickname:
validated_data["nickname_updated_at"] = timezone.now()
return super(BaseUserProfileSerializer, self).update(instance, validated_data)


class PublicUserProfileSerializer(BaseUserProfileSerializer):
class Meta(BaseUserProfileSerializer.Meta):
fields = (
"picture",
"nickname",
"user",
"is_official",
"is_school_admin",
)


class MyPageUserProfileSerializer(BaseUserProfileSerializer):
num_articles = serializers.SerializerMethodField()
num_comments = serializers.SerializerMethodField()
num_positive_votes = serializers.SerializerMethodField()

@staticmethod
def get_num_articles(obj):
from apps.core.models import Article

num_articles = Article.objects.filter(created_by=obj.user).count()
return num_articles

@staticmethod
def get_num_comments(obj):
from apps.core.models import Comment

num_comments = Comment.objects.filter(created_by=obj.user).count()
return num_comments

@staticmethod
def get_num_positive_votes(obj):
from apps.core.models import Vote

num_article_votes = Vote.objects.filter(
parent_article__created_by=obj.user, is_positive=True
).count()
num_comment_votes = Vote.objects.filter(
parent_comment__created_by=obj.user, is_positive=True
).count()
return num_article_votes + num_comment_votes
3 changes: 3 additions & 0 deletions apps/calendar/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
Empty file added apps/calendar/views/__init__.py
Empty file.
1 change: 1 addition & 0 deletions apps/calendar/views/viewsets/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .calendar import *
45 changes: 45 additions & 0 deletions apps/calendar/views/viewsets/calendar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from django.utils import timezone
from rest_framework import decorators, mixins, response, status

from apps.user.models import UserProfile
from apps.user.permissions.user_profile import UserProfilePermission
from apps.user.serializers.user_profile import (
PublicUserProfileSerializer,
UserProfileSerializer,
UserProfileUpdateActionSerializer,
)
from ara.classes.viewset import ActionAPIViewSet


class CalendarViewSet(
mixins.RetrieveModelMixin, mixins.UpdateModelMixin, ActionAPIViewSet
):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
action_serializer_class = {
"update": UserProfileUpdateActionSerializer,
"partial_update": UserProfileUpdateActionSerializer,
}
permission_classes = (UserProfilePermission,)

def retrieve(self, request, *args, **kwargs):
profile = self.get_object()
if request.user == profile.user:
return super().retrieve(request, *args, **kwargs)
else:
return response.Response(PublicUserProfileSerializer(profile).data)

@decorators.action(detail=True, methods=["patch"])
def agree_terms_of_service(self, request, *args, **kwargs):
# BAD_REQUEST if user already agree with the terms of service
if request.user.profile.agree_terms_of_service_at is not None:
return response.Response(
status=status.HTTP_400_BAD_REQUEST,
)

request.user.profile.agree_terms_of_service_at = timezone.now()
request.user.profile.save()

return response.Response(
status=status.HTTP_200_OK,
)
45 changes: 45 additions & 0 deletions apps/calendar/views/viewsets/user_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from django.utils import timezone
from rest_framework import decorators, mixins, response, status

from apps.user.models import UserProfile
from apps.user.permissions.user_profile import UserProfilePermission
from apps.user.serializers.user_profile import (
PublicUserProfileSerializer,
UserProfileSerializer,
UserProfileUpdateActionSerializer,
)
from ara.classes.viewset import ActionAPIViewSet


class UserProfileViewSet(
mixins.RetrieveModelMixin, mixins.UpdateModelMixin, ActionAPIViewSet
):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
action_serializer_class = {
"update": UserProfileUpdateActionSerializer,
"partial_update": UserProfileUpdateActionSerializer,
}
permission_classes = (UserProfilePermission,)

def retrieve(self, request, *args, **kwargs):
profile = self.get_object()
if request.user == profile.user:
return super().retrieve(request, *args, **kwargs)
else:
return response.Response(PublicUserProfileSerializer(profile).data)

@decorators.action(detail=True, methods=["patch"])
def agree_terms_of_service(self, request, *args, **kwargs):
# BAD_REQUEST if user already agree with the terms of service
if request.user.profile.agree_terms_of_service_at is not None:
return response.Response(
status=status.HTTP_400_BAD_REQUEST,
)

request.user.profile.agree_terms_of_service_at = timezone.now()
request.user.profile.save()

return response.Response(
status=status.HTTP_200_OK,
)

0 comments on commit 6f70bec

Please sign in to comment.