본문 바로가기

Backend/Python

[DRF] Django Rest Framework (1)

반응형

기본 구조 세팅

AppSetting

1. apps.py 확인

from django.apps import AppConfig


class StartserviceConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'MunDeuk.startService'

 

2. serializers.py 생성

from django.contrib.auth.models import Group, User
from rest_framework import serializers


# 데이터 표현 (Spring의 DTO와 유사한 느낌)
# => 쿼리셋, 모델 인스턴스와 같은 복잡한 데이터를 JSON, XML과 같이 간단한 데이터로 변환하는 것이라고 한다.
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'groups']


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ['url', 'name']

 

3. views.py 수정

from django.shortcuts import render

# Create your views here.
from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import UserList

from .serializers import GroupSerializer, UserSerializer


# 클라이언트 요청 처리 및 비즈니스로직 수행 (Spring의 Controller와 유사한 느낌)
class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]


class GroupViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Group.objects.all().order_by('name')
    serializer_class = GroupSerializer
    permission_classes = [permissions.IsAuthenticated]


# API 뷰 추가
def index(request):
    return render(request, 'index.html')


class UserListView(APIView):
    def get(self, request):
        users = UserList.objects.all()
        serializer = UserSerializer(users, many=True)
        return Response(serializer.data)

 

4. model 수정

from django.db import models


# Create your models here.
class UserList(models.Model):
    username = models.CharField(max_length=100)
    email = models.CharField(max_length=100)
    group = models.CharField(max_length=100)

    def __str__(self):
        return self.username

 

5. urls.py 생성

from django.urls import path
from .views import index, UserListView # class가져오기

urlpatterns = [
    path('', index, name='index'),
    path('api/users/', UserListView.as_view(), name='user-list'),
]

 

Project Setting

1. urls.py 수정

"""
URL configuration for MunDeuk project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
# from django.contrib import admin
# from django.urls import path
#
# urlpatterns = [
#     path('admin/', admin.site.urls),
# ]

# URL과 뷰 매핑 (Spring의 @RequestMapping과 유사한 느낌)
from django.contrib import admin
from django.urls import include, path
from rest_framework import routers
# from .views import index

from MunDeuk.startService import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    # path('', include(router.urls)),
    path('', include('MunDeuk.startService.urls')),
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

 

2. settings.py 수정

...
import os
...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            # template 추가
            os.path.join(TEMPLATES_DIR, 'templates')
        ],
        ...
    },
]
...
# Pagination
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}
...

 

Template 추가

{프로젝트 디렉토리 경로}/templates/~~.html

 

migration 수행 (model을 수정하거나 추가하면 migration을 진행해야 한다.)

# migrations 생성
python manage.py makemigrations

# migration 실행
python manage.py migrate

# 서버 실행
python manage.py runserver

 

 

 

makemigrations중 만난 에러

RuntimeError: Model class MunDeuk.startService.models.UserList doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
django.core.exceptions.ImproperlyConfigured: Cannot import 'startService'. Check that 'MunDeuk.startService.apps.StartserviceConfig.name' is correct.

 

➡️이 두 에러는 app이름과 경로를 잘못 적어서 그렇다.

 

makemigration을 수행하기 전에 프로젝트명과 앱명이 잘 작성되었는지 아래 3가지를 체크하자.

1. settings.py

INSTALLED_APPS = [
   ...
    # app 추가
    'MunDeuk.startService',
   ...
]

 

2. apps.py

class StartserviceConfig(AppConfig):
    ...
    name = 'MunDeuk.startService'

 

3. 앱명을 작성한 부분에서 프로젝트 명은 빼먹지 않았는지

 


Template가 있지만 경로를 못찾아 500을 띄운 경우이다.

➡️ 파일도 있고 view와 urls의 경로도 맞았다. 그럼 무엇이 문제일까... 하고 로그를 확인했다.

 

이런... Template가 있는 경로까지 DIR이 정해지지 않았다.

 

Settings에서 BASE_DIR이 Project 상위 경로까지만 되어있어 경로를 수정해주었다.

...
TEMPLATES_DIR = BASE_DIR / "MunDeuk"
...
TEMPLATES = [
    {
        ...
        'DIRS': [
            # template 추가
            os.path.join(TEMPLATES_DIR, 'templates')
        ],
        ...
    },
]

 

반응형

'Backend > Python' 카테고리의 다른 글

[DRF] Django Rest Framework (1-2)  (0) 2024.07.12
[DRF] Django Rest Framework (1-1)  (0) 2024.07.11
[DRF] Django Rest Framework (0)  (0) 2024.07.09
[Django] 게시판, 관리자, Superuser  (0) 2024.04.01
[Django] 단순 웹 페이지 구현  (0) 2024.03.28