<모델링>
- Todo 모델을 만들어 주고, url, view에 뭐가 들어가면 좋을지 설계부터 해보자!
- models.py
# lists/models.py
from datetime import timezone
from django.db import models
from users.models import User
class Todo(models.Model):
title = models.CharField("할일", max_length=100)
is_complete = models.BooleanField("완료여부")
created_at = models.DateTimeField("생성일", auto_now_add=True)
updated_at = models.DateTimeField("마지막 수정일", auto_now=True)
completion_at = models.DateTimeField("완료일", blank=True, null=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return str(self.title)
def update_completion_at(self):
self.completion_at = timezone.now()
self.save()
- 제일 고민이 된 게 완료일을 어떻게 넣어주나..였다
- 될지는 모르겠지만 views에서 수정할 때 is_complete가 True이면 완료일에 현재시간을 넣어보자 생각해서 모델에 update_completion_at 함수를 짜봤다
- 근데 예시 보니까 연-월-일만 나와있어서 나중에 형식을 수정해야 할 것 같다
- 일단 할일 등록/조회/수정/삭제 다 구현하고 나중에 수정하도록 하겠다
- urls.py
# lists/urls.py
from django.urls import path
from lists import views
urlpatterns = [
path('', views.TodoListView.as_view(), name='todo_list_view'),
path('<int:todo_id>/', views.TodoView.as_view(), name='todo_view'),
]
- url은 2개만 있으면 될 것 같다
- views.py
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.decorators import permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.generics import get_object_or_404
@permission_classes([IsAuthenticated])
class TodoListView(APIView):
def post(self, request):
"""할일 등록"""
return Response("POST 요청!")
def get(self, request):
"""할일 조회"""
return Response("GET 요청!")
@permission_classes([IsAuthenticated])
class TodoView(APIView):
def put(self, request):
"""할일 수정"""
return Response("PUT 요청!")
def delete(self, request):
"""할일 삭제"""
return Response("DELETE 요청!")
<할일 등록>
- serializers.py
# lists/serializers.py
from rest_framework import serializers
from lists.models import Todo
class CreateTodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ("title", "is_complete")
- 할일과 완료여부만 쓰면 될 것 같아서 CreateTodoSerializer를 따로 만들었다
- views.py
# lists/views.py
...
from lists.serializers import CreateTodoSerializer
...
@permission_classes([IsAuthenticated])
class TodoListView(APIView):
def post(self, request):
"""할일 등록"""
serializer = CreateTodoSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
<할일 조회>
- 할일 조회는 작성자 본인의 할일 목록만 조회할 수 있다
- serializers.py
# lists/serializers.py
...
class TodoListSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
exclude = ("user",)
- 과제 예시에 user 필드 빼고 다 있길래 exclude를 사용했다
- views.py
# lists/views.py
...
from lists.models import Todo
from lists.serializers import TodoListSerializer
...
@permission_classes([IsAuthenticated])
class TodoListView(APIView):
...
def get(self, request):
"""할일 조회"""
todo_lists = Todo.objects.filter(user=request.user)
serializer = TodoListSerializer(todo_lists, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
- 로그인 한 자신의 할일 목록만 조회된다
<할일 수정>
- 원래 내가 하고 싶었던 건 is_complete가 True로 바뀌면 완료일을 그 날짜가 되게끔 하고 더이상 수정이 불가한 걸 만들고 싶었다
- 근데 도대체 뭐라고 검색해야 하는지 모르겠고 튜터님들은 안 계시고 누구한테 물어봐약 할지도 모르겠어서 구현을 못 했다
- 그냥 이용자가 날짜를 선택하게끔 했따..
- is_complete가 True일 때만 완료일을 설정할 수 있게끔 하고 싶은데.....애초에 views.py를 어떻게 짜야하는지....모르겠다ㅠㅠ
- views.py
# lists/views.py
...
@permission_classes([IsAuthenticated])
class TodoView(APIView):
def put(self, request, todo_id):
"""할일 수정"""
todo = get_object_or_404(Todo, id=todo_id)
if request.user == todo.user:
serializer = CreateTodoSerializer(todo, data=request.data)
print(request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response("권한이 없습니다!", status=status.HTTP_403_FORBIDDEN)
- serializers.py
# lists/serializers.py
...
class CreateTodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ("title", "is_complete", "completion_at")
- urls.py는 이미 위에서 추가했고 시리얼라이저는 필드를 추가했다
<할일 삭제>
- 삭제는 간단하다 views.py만 작성하면 된다
- views.py
# lists/views.py
...
@permission_classes([IsAuthenticated])
class TodoView(APIView):
...
def delete(self, request, todo_id):
"""할일 삭제"""
todo = get_object_or_404(Todo, id=todo_id)
if request.user == todo.user:
todo.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
else:
return Response("권한이 없습니다!", status=status.HTTP_403_FORBIDDEN)