[Django] MariaDB 연동

최병훈·2024년 9월 24일
post-thumbnail

1. Model

  • 데이터 서비스를 제공하는 레이어
  • 애플리케이션 안에 자동으로 생성되는 modes.py 파일에 정의
  • 클래스 단위로 정의를 하는데 하나의 클래스는 하나의 테이블과 매핑됩니다.
  • 모델 클래스를 만들 때는 Model 이라는 클래스로부터 상속을 받아야 합니다.
  • primary key를 설정하지 않으면 테이블을 생성할 때 자동으로 id가 생성됩니다.
  • 속성을 생성하면 테이블의 컬럼이 만들어지는데 models에 있는 여러 종류의 클래스를 이용하고 각 클래스마다 생성할 때 여러 옵션을 설정하는 것이 가능합니다.
  • 대다수의 ORM은 테이블이 존재하지 않으면 테이블을 자동으로 생성해주고, 제약 조건은 속성의 자료형에 해당하는 클래스에서 생성자나 메서드를 통해서 지정이 가능합니다.

2. mariadb 나 mysql 사용을 위한 설정

  • mysqlclient 패키지 설치

    pip install mysqlclient
  • settings.py 파일의 DATABASE 설정 부분을 수정

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': '데이터베이스이름',
            'USER' : '계정',
            'PASSWORD' : '비밀번호',
            'HOST' : '데이터베이스 URL',
            'PORT' : '포트번호(기본 포트를 사용하는 경우 빈칸)'
        }
    }
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'django',
            'USER' : 'root',
            'PASSWORD' : 'mypassword',
            'HOST' : '127.0.0.1',
            'PORT' : ''
        }
    }
  • 데이터베이스 정보를 수정한 경우는 2개의 명령어를 재실행

    python manage.py makemigrations
    python manage.py migrate
  • 데이터베이스 접속 프로그램(dbeaver)을 사용하여 migrate 되었는지 확인

  • 테이블 자동 생성

    • models.py 파일에 models.Model 클래스를 상속받는 클래스를 생성
      # 데이터베이스에서 사용할 테이블과 클래스를 매빙하는 부분
      from django.db import models
      from enum import unique
      
      class Owner(models.Model):
          name = models.CharField(max_length=128, unique=True)
          email = models.EmailField(unique=True)
          phone = models.CharField(max_length=128)
      
      class Brand(models.Models):
          brand_name = models.CharField(max_length=128, unique=True)
      
      class CarModel(models.Model):
          brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
          model_name = models.CharField(max_length=128)
      
      class Car(models.Model):
          car_number = models.CharField(max_length=128)
          owner = models.ForeignKey(Owner, on_delete=models.CASCADE)
          car_model = models.ForeignKey(CarModel, on_delete=models.CASCADE)    
    • models.py 파일을 수정하면 2개의 명령어를 다시 수행
      python manage.py makemigrations
      python manage.py migrate
    • models.py 파일에 정의된 클래스를 가지고 일치하는 이름의 테이블이 있는지 확인해서 없으면 생성
      • 생성되는 테이블명 : 애플리케이션이름_클래스이름
        (mysql이나 mariadb는 소문자로 변경해서 테이블을 생성)

  • 테이블을 SQL을 통해 생성한 후 클래스와 매핑
    • myweb_item 테이블 생성 및 데이터 insert
      create table myweb_item(
      	itemid int primary key,
      	itemname varchar(20),
      	price int,
      	description varchar(50),
      	pictureurl varchar(20)
      );
      
      insert into myweb_item values(1, 'Lemon', 500, 'Vitamin-A', 'lemon.jpg');
      insert into myweb_item values(2, 'Orange', 1500, 'Vitamin-C', 'orange.jpg');
      
      select * from myweb_item;
    • models.py 파일에 테이블과 매핑될 클래스 생성
      class Item(models.Model):
          itemid = models.IntegerField(primary_key=True)
          itemname = models.CharField(max_length=20)
          price = models.IntegerField()
          description = models.CharField(max_length=50)
          pictureurl = models.CharField(max_length=20)
    • models.py 파일을 수정한 후 다음 명령어 수행
      python manage.py makemigrations

3. CRUD 작업

데이터 삽입

  • 인스턴스를 만들고 save 메서드 호출

데이터 조회

  • Model 클래스에는 objects 라는 Manager 클래스 인스턴스가 존재
  • objects 라는 인스턴스를 통해서 필터링 및 정렬 등의 작업을 수행
  • item 테이블의 모든 데이터를 조회
    • item.objects.all() 을 호출하면 반복 가능한 컬렉션으로 데이터를 리턴합니다.
    • get, filter, exclude, count, order_by, distinct, first, last 와 같은 여러 메서드가 존재

데이터 수정

  • 데이터를 조회한 후, 필요한 속성의 값을 수정하고 save 를 호출

데이터 삭제

  • 데이터를 조회한 후, delete 를 호출

Item 테이블의 전체 데이터 조회

  • views.py 파일의 index 함수를 수정
def index(request):
    # Item 테이블의 모든 데이터를 가져오기
    data = Item.objects.all()
	# 데이터를 템플릿에 넘겨주기
    return render(request, 'index.html', {'data':data})
  • 템플릿 엔진을 사용해서 정적 파일(HTML, CSS, JavasScript 그리고 HTML을 출력하기 위해서 필요한 파일들)을 사용할 때는 별도의 설정을 추가

    • settings.py 파일에 정적파일의 디렉토리 설정 코드를 추가
    # 정적 파일을 저장할 디렉토리 설정
    STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
  • myweb 디렉토리 안에 static 디렉토리를 생성하고 그 안에 css 디렉토리를 생성하고 style.css 파일을 생성하고 작성

    div.body{
        margin-top: 50px;
        margin-bottom: 50px;
    }
    tr.header{
        background: #C9BFED;
    }
    tr.record{
        background: #EDEDED;
    }
  • index.html 파일 수정

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>장고</title>
        <link rel="stylesheet" href="{% static 'css/style.css' %}">
    </head>
    <body>
        <div align="center" class="body">
            <h3>목록 보기</h3>
            <table border="1">
                <tr class="header">
                    <th align="center" width="80">ID</th>
                    <th align="center" width="320">이름</th>
                    <th align="center" width="100">가격</th>
                </tr>
    
                {% for item in data %}
                    <tr class="record">
                        <td align="center">{{item.itemid}}</td>
                        <td align="center">{{item.itemname}}</td>
                        <td align="center">{{item.price}}</td>
                    </tr>
                {% endfor %}
            </table>
        </div>
    </body>
    </html>
  • 브라우저에서 접속하여 결과 확인

    • 데이터베이스의 데이터를 불러와서 템플릿에 넘겨주고 html이 구성되어 보여진다.

itemid를 url에서 넘겨받아 하나의 데이터 가져오기

  • urls.py 파일에 요청을 추가

    from django.contrib import admin
    from django.urls import path
    # myweb 애플리케이션에 있는 views.py 의 내용 가져오기
    from myweb import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', views.index),
        path('get/<str:itemid>', views.getItem),
        path('querystring', views.queryString),
        path('requestbody', views.requestBody),
        path('formdata', views.formData),
        path('fileupload', views.fileUpload),
        path('cookiecreate', views.cookieCreate),
        path('cookieread', views.cookieRead),
        # 요청 추가
        path('detail/<int:itemid>', views.detail),
    ]
  • views.py 파일에 detail 함수 추가

    def detail(request, itemid):
        # itemid 의 값이 itemid 인 데이터 1개 가져오기
        item = Item.objects.get(itemid=itemid)
        return HttpResponse(item)
  • API 테스트 도구로 "127.0.0.1:8000/detail/itemid" 형태로 테스트

    • itemid 가 1인, Item 객체가 불러와진다.

데이터 삽입 구현

  • urls.py 파일에 삽입을 위한 요청을 생성

    from django.contrib import admin
    from django.urls import path
    # myweb 애플리케이션에 있는 views.py 의 내용 가져오기
    from myweb import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', views.index),
        path('get/<str:itemid>', views.getItem),
        path('querystring', views.queryString),
        path('requestbody', views.requestBody),
        path('formdata', views.formData),
        path('fileupload', views.fileUpload),
        path('cookiecreate', views.cookieCreate),
        path('cookieread', views.cookieRead),
    
        path('detail/<int:itemid>', views.detail),
        # 요청 추가
        path('item', views.insert),
    ]
  • views.py 파일에 insert 함수 추가

    from django.db.models import Max
    from django.shortcuts import redirect
    def insert(request):
        item = Item()
    
        # 가장 큰 itemid 를 찾아서 +1 을 해서 새로운 itemid 생성
        obj = Item.objects.aggregate(itemid=Max("itemid"))
        if obj['itemid'] == None:
            obj['itemid'] = 0
        item.itemid = int(obj['itemid']) + 1
    
        item.itemname = "name"
        item.description = "description"
        item.price = 3000
        item.pictureurl = "imageurl"
        item.save()
    
        # 작업이 끝난 후 시작 페이지로 리다이렉트
        return redirect("/")
  • POSTMAN 을 통해 삽입 요청 "127.0.0.1:8000/item"

    • "/item" 으로 삽입 요청 이후, "/" 시작페이지로 리다이렉트 되었다.
  • dbeaver 를 통해 데이터 삽입이 되었는지 확인

데이터 수정

from django.shortcuts import redirect
def update(request):
    # 데이터를 찾아옵니다.
    item = Item.objects.get(itemid=1)
    # 데이터 수정
    item.itemname = "1"
    # 수정된 내용 저장
    item.save()

    # 작업이 끝난 후 시작 페이지로 리다이렉트
    return redirect("/")

데이터 삭제

from django.shortcuts import redirect
def delete(request):
    # 데이터를 찾아옵니다.
    item = Item.objects.get(itemid=1)
    # 데이터 삭제
    item.delete()

    # 작업이 끝난 후 시작 페이지로 리다이렉트
    return redirect("/")

1개의 댓글

comment-user-thumbnail
2024년 9월 25일

정리가 잘되어있네요ㅎㅎ 덕분에 Mariadb 연동 했어요👍

답글 달기