Django : python으로 웹서비스 개발하기(5) - 데이터베이스 데이터 읽기

harry jang·2023년 7월 8일
0

Django

목록 보기
5/12
post-thumbnail

데이터 읽어오기

테이블 생성하기

Mysql 워크벤치를 통해서 사용할 테이블을 하나 생성합니다.

CREATE TABLE testdb.test_member(
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    age INT NOT NULL,
    created_at DATETIME NOT NULL DEFAULT NOW(), 
    updated_at DATETIME NULL DEFAULT NULL ON UPDATE NOW(),
    PRIMARY KEY (id)
);

확인을 위해 생성된 테이블에 데이터도 몇개 삽입해줍니다.

INSERT INTO `testdb`.`test_member`
(`name`,
`age`)
VALUES
('harry', 34),
('john', 42),
('rachel', 24);

모델 생성하기

모델이란 부가적인 메타데이터를 가진 데이터베이스의 구조(layout)를 말합니다.
Djangomodels.py로 테이블을 생성할 수 있지만 반대로 기존에 존재하는 DB의 테이블을 가져올 수도 있습니다.
이미 존재하는 테이블을 model.py로 만드려면 아래의 명령을 프롬프트에 입력합니다.

$ python manage.py inspectdb > models.py

이렇게 입력하면 명령을 입력한 디렉토리에 default로 연결된 db에 대한 모델파일인 models.py 파일이 만들어집니다.
만약 default db외에 별도의 db를 연결한 상태라면 아래의 명령으로 해당 db의 모델파일을 생성할 수 있습니다.

$ python manage.py inspectdb --datebase DB명 > models.py

만들어진 models.pytest_app/ 디렉토리 하위에 넣어서 덮어쓰기를 합니다.

특정 테이블의 데이터 모두 읽어 들이기

데이터를 읽어들이기 전에 Django의 API 기능을 사용하기 위해 아래의 명령으로 패키지를 설치합니다.

$ pip install djangorestframework

설치한 패키지를 사용하기 위해 settings.py파일을 수정해보겠습니다. rest_framework와 우리가 만든 앱인 test_app도 같이 포함시켜 INSTALLED_APPS 항목에 추가해 줍니다.

...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'test_app',
    'rest_framework',
]
...

다음으로 모델을 직렬화하기 위해 test_app/ 디렉토리 하위에 serializer.py 파일을 생성하고 다음과 같은 코드를 작성합니다.

from rest_framework.serializers import ModelSerializer
from models import TestMember

class TestMemberSerializer(ModelSerializer):
    class Meta:
        model = TestMember
        fields = '__all__'

직렬화란?
객체를 바이트 스트림으로 변환하는 것, 즉 객체에 저장된 데이터 스트림에 쓰기 위해 연속적인 직렬 데이터로 변환하는 것이다.
쉬운 예로 DB에서 불러온 데이터를 json으로 보여주기 위해 가공하는 부분으로 이해하시면 될 것 같습니다.

코드에 대해 간략히 설명하자면, 아까 설치했던 rest_framework 패키지내의 ModelSerializerinspectdb 명령을 통해 생성되었던 models.py 내의 TestMember 테이블 클래스을 가져와서 test_member 테이블의 데이터를 직렬화하여 TestMember 클래스로 변환해주는TestMemberSerializer 클래스를 생성하였습니다.
이제 TestMember 클래스 오브젝트로 db데이터를 읽어오고, TestMemberSerializer로 사용자가 볼 수 있게 데이터를 변환할 수 있게 되었습니다.

확인을 위해 인덱스 페이지를 수정해 봅시다. views.py파일을 열어 다음과 같이 수정합니다.

from .models import TestMember
from .serializer  import TestMemberSerializer
from django.http import HttpResponse

def index(request):
    datas = TestMember.objects.all()
    serializer = TestMemberSerializer(datas, many=True)

    return HttpResponse(serializer.data)

서버를 실행하여 인덱스 페이지를 열어봅니다.

$ python manage.py runserver


다음과 같은 내용이 노출된다면 DB에서 데이터를 정상적으로 가져온 것입니다.

rest_framework 패키지를 설치한 김에 API 형태로도 내용을 노출해봅시다.
views.py를 다음과 같이 작성합니다.

from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import TestMember
from .serializer  import TestMemberSerializer
from django.http import HttpResponse

@api_view(['GET'])
def getTestMembers(request):
    datas = TestMember.objects.all()
    serializer = TestMemberSerializer(datas, many=True)
    return Response(serializer.data)

@api_view(['GET'])
def getTestMember(request, name):
    data = TestMember.objects.get(name=name)
    serializer = TestMemberSerializer(data, many=False)
    return Response(serializer.data)

def index(request):
    datas = TestMember.objects.all()
    serializer = TestMemberSerializer(datas, many=True)

    return HttpResponse(serializer.data)

그리고 test_app/내의 urls.py 파일에 추가한 api의 url를 등록해줍니다.

from django.urls import path
from . import views

urlpatterns = [
	path("members/", views.getTestMembers, name="getMembers"),
    path("member/<str:name>", views.getTestMember, name="getMember"),
	path("hello/", views.index, name="index"),
]

/members API는 테이블 데이터 전체조회를 하는 API이고,
/member/<str:name> API는 테이블에서 해당되는 이름의 데이터만 검색하는 API입니다. <str:name>member/ 뒤에 붙는 Path Parameter로 검색할 이름을 저장하는 String 타입의 변수입니다.

예를 들어 'harry'라는 이름의 멤버를 검색하려면 /member/harry로 url을 호출하면 harry에 대한 정보만 검색이 됩니다.

작성을 마치고 브라우저를 통해 호출해보면 아래 그림과 같이 정상적으로 데이터를 읽어올 수 있습니다.

멤버 전체 조회

멤버 검색

profile
software engineer

0개의 댓글