Django에서의 데이터베이스 연동
Model
- 데이터 서비스를 제공하는 레이어
- 애플리케이션안에 자동으로 생성되는 models.py 파일에 정의
- 클래스 단위로 정의를 하는데 하나의 클래스는 하나의 테이블과 매팽됨
- 모델 클래스를 만들때는 Model 이라는 클래스로부터 상속을 받아야 함
- Primary Key를 설정하지 않으면 테이블을 생성할 때 자동으로 id가 생성됨
- 속성을 생성하면 테이블의 컬럼이 만들어지는데 models에 있는 여러 종류의 클래스를 이용하고 각 클래스마다 생성을 할 때 여러 옵션을 설정하는 것이 가능
- 대다수의 ORM은 테이블이 존재하지 않으면 테이블을 자동으로 생성해주고 제약 조건은 속성의 자료형에 해당하는 클래스에서 생성자나 메서드를 통해서 지정이 가능
mariadb나 mysql 사용을 위한 설정
- mysqlclient라는 패키지가 필요
- settings.py 파일의 DATABASE 설정 부분을 수정
DATABASES = {
'default':{
'ENGINE':'django.db.backends.mysql',
'NAME':'데이터베이스이름',
'USER':'계정',
'PASSWORD':'비밀번호',
'HOST':'데이터베이스URL',
'PORT':'포트번호인데 기본 포트를 사용하는 경우 빈 칸으로 설정 가능'
}
}
- 데이터베이스 정보를 수정한 경우는 2개의 명령어를 재실행
python manage.py makemigrations
python manage.py migrate
- 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)
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 함수를 수정
from myweb.models import Item
# Create your views here.
def index(request):
# Item테이블의 모든 데이터를 가져오기
data = Item.objects.all()
return render(request, 'index.html', {'data': data})
- 템플릿 엔진을 사용해서 정적 파일(HTML, CSS, JavaScript, HTML을 출력하기 위해서 필요한 파일들)을 사용할 때는 별도의 설정을 추가: settings.py 파일에 정적 파일의 디렉터리 설정 코드를 추가
# 정적 파일을 저장할 디렉터리 설정
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
- myweb 디렉터리 안에 static 디렉터리를 생성하고 그 안에 css 디렉터리를 생성하고 style.css 파일을 생성하고 작성
div.body {
margin-top: 50psx;
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>
<h3>{{message}}</h3>
</body>
</html>
- itemid를 url에서 넘겨받아 하나의 데이터가져오기
- urls.py 파일에 요청을 추가
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 테스트 도구를 가지고 detail/존재하는id
- 데이터 삽입 구현
- urls.py 파일에 삽입을 위한 요청을 생성
path('item', views.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.description = "description"
item.price = 3000
item.pictureurl = "image"
item.itemname = "무화과"
item.save()
# 시작 페이지로 리다이렉트
return redirect("/")
- SPA(Single Page Application - 하나의 페이지에서 모든 작업을 수행하는 애플리케이션: angular, vue, react가 SPA를 구현하는 프레임워크)가 아닌 경우 페이지 이동 방법
- forwarding: 조회에 주로 이용
- 이전 흐름을 유지하면서 이동
- request객체가 다시 생성되지 않고 이전 객체를 계속 유지
- 새로고침을 하게 되면 요청 처리 메서드가 다시 호출됨
- redirect: 조회 이외의 작업에 주로 이용
- 이전 흐름을 유지하지 않고 이동
- request 객체는 다시 생성되고 session 객체는 유지
- 새로고침을 하게 되면 요청 처리 메서드는 호출되지 않고 결과만 다시 보여짐
- forwarding: 조회에 주로 이용