개요
장고 프레임워크를 사용하여 기본적인 CRUD 기능과, REST API를 구현하는 방법을 알아보자.
프로젝트 구조
1.
2├── db.sqlite3
3├── djtest (메인 앱)
4│ ├── __init__.py
5│ ├── asgi.py
6│ ├── settings.py
7│ ├── urls.py
8│ ├── views.py
9│ └── wsgi.py
10├── manage.py
11├── paste (생성한 앱)
12│ ├── __init__.py
13│ ├── admin.py
14│ ├── apps.py
15│ ├── migrations
16│ ├── models.py
17│ ├── serializers.py
18│ ├── tests.py
19│ ├── urls.py
20│ └── views.py
21└── requirements.txt
자주 쓰는 명령어
1# 새로운 Django 프로젝트를 생성
2python manage.py startproject
3# 새로운 Django 앱을 생성
4python manage.py startapp
5# 데이터베이스에 적용할 마이그레이션 파일을 생성
6python manage.py makemigrations
7# 마이그레이션 파일을 실제 데이터베이스에 적용
8python manage.py migrate
9# 관리자(superuser) 계정을 생성
10python manage.py createsuperuser
11# 프로젝트의 테스트 케이스를 실행
12python manage.py test
13# 테스트용 서버를 특정 설정으로 실행
14python manage.py testserver
CRUD 구현
Paste Model 정의
1from django.db import models
2
3class Paste(models.Model):
4 title = models.CharField(max_length=100)
5 content = models.TextField()
6 # auto_now_add : 객체가 처음 생성될 때만 현재 날짜와 시간을 자동으로 설정
7 created_at = models.DateTimeField(auto_now_add=True)
8 # auto_now : 객체가 저장될 때마다 현재 날짜와 시간을 자동으로 설정
9 updated_at = models.DateTimeField(auto_now=True)
10 class Meta:
11 ordering = ['-created_at']
12 def __str__(self):
13 return self.title
Paste Serializer 정의
1from rest_framework import serializers
2from .models import Paste
3
4class PasteSerializer(serializers.ModelSerializer):
5 class Meta:
6 model = Paste
7 fields = '__all__'
8 # 직접 지정하는 방법
9 # fields = ['title', 'content']
View 구현
- PasteView
1class PasteView(APIView):
2 def get(self, _):
3 pastes = Paste.objects.all()
4 serializer = PasteSerializer(pastes, many=True)
5 return Response(serializer.data, status=status.HTTP_200_OK)
6
7 def post(self, request):
8 serializer = PasteSerializer(data=request.data)
9 if serializer.is_valid():
10 serializer.save(user=request.user)
11 return Response(serializer.data, status=status.HTTP_201_CREATED)
12 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
- PasteDetailView
1class PasteDetailView(APIView):
2 def get(self, _, pk):
3 try:
4 paste = Paste.objects.get(pk=pk)
5 serializer = PasteSerializer(paste)
6 return Response(serializer.data, status=status.HTTP_200_OK)
7 except Paste.DoesNotExist:
8 return Response(status=status.HTTP_404_NOT_FOUND)
9
10 def put(self, request, pk):
11 try:
12 paste = Paste.objects.get(pk=pk)
13 except Paste.DoesNotExist:
14 return Response(status=status.HTTP_404_NOT_FOUND)
15
16 if paste.user != request.user:
17 return Response(status=status.HTTP_403_FORBIDDEN)
18
19 serializer = PasteSerializer(paste, data=request.data)
20 if serializer.is_valid():
21 serializer.save()
22 return Response(serializer.data, status=status.HTTP_200_OK)
23 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
24
25 def delete(self, request, pk):
26 try:
27 paste = Paste.objects.get(pk=pk)
28 except Paste.DoesNotExist:
29 return Response(status=status.HTTP_404_NOT_FOUND)
30
31 paste.delete()
32 return Response(status=status.HTTP_204_NO_CONTENT)
urls.py
1from django.urls import path
2from paste.views import *
3
4urlpatterns = [
5 path('', PasteView.as_view(), name='paste_list_create'),
6 path('<int:pk>', PasteDetailView.as_view(), name='paste_get_update_delete'),
7]
Swagger 적용
PasteView
- PasteView
1class PasteView(APIView):
2 @swagger_auto_schema(
3 operation_description="Get list of pastes",
4 operation_summary="Get list of pastes",
5 responses={200: PasteSerializer(many=True)},
6 )
7 def get(self, _):
8 ...
9
10 @swagger_auto_schema(
11 operation_description="Create a new paste",
12 operation_summary="Create a new paste",
13 request_body=PasteSerializer,
14 responses={201: PasteSerializer, 400: "Bad Request"},
15 )
16 def post(self, request):
17 ...
- PasteDetailView
1class PasteDetailView(APIView):
2 @swagger_auto_schema(
3 operation_description="Get a paste by ID",
4 operation_summary="Get a paste by ID",
5 responses={200: PasteSerializer, 404: "Not Found"},
6 )
7 def get(self, _, pk):
8 ...
9
10 @swagger_auto_schema(
11 operation_description="Update a paste by ID",
12 operation_summary="Update a paste by ID",
13 request_body=PasteSerializer,
14 responses={
15 200: PasteSerializer,
16 400: "Bad Request",
17 403: "Forbidden",
18 404: "Not Found",
19 },
20 )
21 def put(self, request, pk):
22 ...
23
24 @swagger_auto_schema(
25 operation_description="Delete a paste by ID",
26 operation_summary="Delete a paste by ID",
27 responses={204: "No Content", 404: "Not Found"},
28 )
29 def delete(self, request, pk):
30 ...