Skip to content

Commit

Permalink
Merge pull request #430 from sparcs-kaist/feat/calendar
Browse files Browse the repository at this point in the history
Add calendar
  • Loading branch information
injoonH authored Jan 5, 2024
2 parents c6f976b + 1a41c8a commit 9a01656
Show file tree
Hide file tree
Showing 19 changed files with 379 additions and 1 deletion.
Empty file added apps/calendar/__init__.py
Empty file.
37 changes: 37 additions & 0 deletions apps/calendar/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from django.contrib import admin

from ara.classes.admin import MetaDataModelAdmin

from .models import Event, Tag


@admin.register(Event)
class EventAdmin(MetaDataModelAdmin):
list_display = (
"ko_title",
"en_title",
"is_all_day",
"start_at",
"end_at",
"location",
"url",
)
fields = (
("ko_title", "ko_description"),
("en_title", "en_description"),
("start_at", "end_at"),
"is_all_day",
"location",
"url",
"tags",
)
filter_horizontal = ("tags",)


@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
list_display = (
"colored_ko_name",
"en_name",
"color",
)
5 changes: 5 additions & 0 deletions apps/calendar/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class CalendarConfig(AppConfig):
name = "apps.calendar"
124 changes: 124 additions & 0 deletions apps/calendar/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Generated by Django 4.2.3 on 2024-01-03 07:17

import datetime

import django.utils.timezone
from django.db import migrations, models


class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="Tag",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"ko_name",
models.CharField(max_length=255, unique=True, verbose_name="한글 이름"),
),
(
"en_name",
models.CharField(max_length=255, unique=True, verbose_name="영어 이름"),
),
(
"color",
models.CharField(
default="#000000", max_length=7, verbose_name="HEX 코드"
),
),
],
options={
"verbose_name": "태그",
"verbose_name_plural": "태그 목록",
},
),
migrations.CreateModel(
name="Event",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"created_at",
models.DateTimeField(
db_index=True,
default=django.utils.timezone.now,
verbose_name="생성 시간",
),
),
(
"updated_at",
models.DateTimeField(
auto_now=True, db_index=True, verbose_name="수정 시간"
),
),
(
"deleted_at",
models.DateTimeField(
db_index=True,
default=datetime.datetime(
1, 1, 1, 0, 0, tzinfo=datetime.timezone.utc
),
verbose_name="삭제 시간",
),
),
(
"is_all_day",
models.BooleanField(default=False, verbose_name="하루 종일"),
),
("start_at", models.DateTimeField(verbose_name="시작 시각")),
("end_at", models.DateTimeField(verbose_name="종료 시각")),
("ko_title", models.CharField(max_length=512, verbose_name="한글 제목")),
("en_title", models.CharField(max_length=512, verbose_name="영어 제목")),
(
"ko_description",
models.TextField(
blank=True, max_length=512, null=True, verbose_name="한글 설명"
),
),
(
"en_description",
models.TextField(
blank=True, max_length=512, null=True, verbose_name="영어 설명"
),
),
(
"location",
models.CharField(
blank=True, max_length=512, null=True, verbose_name="장소"
),
),
("url", models.URLField(blank=True, null=True, verbose_name="URL")),
(
"tags",
models.ManyToManyField(
blank=True, to="calendar.tag", verbose_name="태그"
),
),
],
options={
"verbose_name": "일정",
"verbose_name_plural": "일정 목록",
"ordering": ("-created_at",),
"abstract": False,
},
),
]
Empty file.
2 changes: 2 additions & 0 deletions apps/calendar/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .event import Event
from .tag import Tag
62 changes: 62 additions & 0 deletions apps/calendar/models/event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from django.db import models

from ara.db.models import MetaDataModel


class Event(MetaDataModel):
is_all_day = models.BooleanField(
verbose_name="하루 종일",
default=False,
)
start_at = models.DateTimeField(
verbose_name="시작 시각",
)
end_at = models.DateTimeField(
verbose_name="종료 시각",
)

ko_title = models.CharField(
verbose_name="한글 제목",
max_length=512,
)
en_title = models.CharField(
verbose_name="영어 제목",
max_length=512,
)
ko_description = models.TextField(
verbose_name="한글 설명",
max_length=512,
blank=True,
null=True,
)
en_description = models.TextField(
verbose_name="영어 설명",
max_length=512,
blank=True,
null=True,
)

location = models.CharField(
verbose_name="장소",
max_length=512,
blank=True,
null=True,
)
url = models.URLField(
verbose_name="URL",
max_length=200,
blank=True,
null=True,
)
tags = models.ManyToManyField(
verbose_name="태그",
to="calendar.Tag",
blank=True,
)

class Meta(MetaDataModel.Meta):
verbose_name = "일정"
verbose_name_plural = "일정 목록"

def __str__(self) -> str:
return self.ko_title
36 changes: 36 additions & 0 deletions apps/calendar/models/tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from django.contrib import admin
from django.db import models
from django.utils.html import format_html


class Tag(models.Model):
ko_name = models.CharField(
verbose_name="한글 이름",
max_length=255,
unique=True,
)
en_name = models.CharField(
verbose_name="영어 이름",
max_length=255,
unique=True,
)
color = models.CharField(
verbose_name="HEX 코드",
max_length=7,
default="#000000",
)

class Meta:
verbose_name = "태그"
verbose_name_plural = "태그 목록"

def __str__(self) -> str:
return self.ko_name

@admin.display(description="한글 이름")
def colored_ko_name(self):
return format_html(
"<span style='color: {}'>{}</span>",
self.color,
self.ko_name,
)
Empty file.
22 changes: 22 additions & 0 deletions apps/calendar/serializers/event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from rest_framework import serializers

from apps.calendar.models import Event


class EventSerializer(serializers.ModelSerializer):
class Meta:
model = Event
fields = [
"id",
"is_all_day",
"start_at",
"end_at",
"ko_title",
"en_title",
"ko_description",
"en_description",
"location",
"url",
"tags",
]
depth = 1
9 changes: 9 additions & 0 deletions apps/calendar/serializers/tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import serializers

from apps.calendar.models import Tag


class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = "__all__"
12 changes: 12 additions & 0 deletions apps/calendar/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.urls import include, path
from rest_framework.routers import DefaultRouter

from .views import EventViewSet, TagViewSet

router = DefaultRouter()
router.register(r"events", EventViewSet, basename="event")
router.register(r"tags", TagViewSet, basename="tag")

urlpatterns = [
path("api/calendar/", include(router.urls)),
]
2 changes: 2 additions & 0 deletions apps/calendar/views/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .event import EventViewSet
from .tag import TagViewSet
9 changes: 9 additions & 0 deletions apps/calendar/views/event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import viewsets

from apps.calendar.models import Event
from apps.calendar.serializers.event import EventSerializer


class EventViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer
9 changes: 9 additions & 0 deletions apps/calendar/views/tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import viewsets

from apps.calendar.models import Tag
from apps.calendar.serializers.tag import TagSerializer


class TagViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Tag.objects.all()
serializer_class = TagSerializer
1 change: 1 addition & 0 deletions ara/settings/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"django_filters",
"apps.core",
"apps.user",
"apps.calendar",
]

MIDDLEWARE = [
Expand Down
1 change: 1 addition & 0 deletions ara/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
path("api/admin/", admin.site.urls),
path("", include(("apps.core.urls", "core"))),
path("", include(("apps.user.urls", "user"))),
path("", include(("apps.calendar.urls", "calendar"))),
path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
path(
"api/schema/swagger/",
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def set_admin_client(request):
agree_terms_of_service_at=timezone.now(),
)
client = APIClient()
client.force_authenticate(user=request.cls.user)
client.force_authenticate(user=request.cls.admin)
request.cls.api_client = client


Expand Down
Loading

0 comments on commit 9a01656

Please sign in to comment.