어떤 정보의 요청에 대해 DB를 관리하는 곳이 Model이다. Template과 View에 요청된 정보를 제공한다.
데이터베이스는 창고의 개념을 넘어서 정보를 구조화 한다. RDB relational DB로서 테이블row,record column,attribute의 형태로 정보를 보관한다. pandas의 DF와 유사하다. SQL은 DB에서 정보를 가져오는데 사용하는 프로그래밍 언어이다. django는 SQL을 사용할 수 있지만 내장되어 있는ORM object을 사용해서 DB를 다룰 수 있다.
homepage디렉토리에서
from django.db import models
# class단위로 상속을 이용해 모델을 만든다.
# class <모델 이름>(models.Model):
class Coffe(models.Model):
#각 필드를 어떤 dtype으로 할지를 정한다.
#field1 = model.FieldType()...
#문자열 : CharField
#숫자 : IntegerField, SmallIntegerField
#논리형 : BooleanField
#시간/날짜 : DateTimeField
#필드의 제약조건을 정해줄 수 있다.
name = models.CharField(default="", max_length=30)
price = models.IntegerField(default=0)
is_ice = models.BooleanField(default=False)
from django.contrib import admin
# models.py를 불러와야 한다.
from .models import Coffee
admin.site.Register(Coffee)
admin페이지에서 Coffee를 수정하려 해도 migration을 먼저 해주어야 한다.
DB의 필드 정보를 수정하더라도 바로 반영이 되지 않고 migration을 진행해야 반영이 된다.
#git add
python manage.py makemigrations homepage
#git commit
python manage.py migrate
#__str__은 object의 이름을 정해주는 역할이다.
class Coffe(models.Model):
def __str__(self):
return self.name
name = models.CharField(default="", max_length=30)
price = models.IntegerField(default=0)
is_ice = models.BooleanField(default=False)
view를 기준으로 model과 template이 소통하는 방식이다.
from .models import Coffee
def coffee_view(request):
#데이터의 정보를 모두 담아온다.
coffee_all = Coffee.objects.all()
return render(request, 'coffee.html',{"coffee_list":coffee_all})
template에 새로운 파일을 만들어 준다.
<!DOCTYPE html>
</html>
<head>
<title>Coffee List</title>
</head>
<body>
<h1>My Coffee List</h1>
<p>{{ coffee_list }}</p>
</body>
</html>
#import 구문 추가
from homepage.views import coffee_view
#urlpatterns에 추가
path('coffee/',coffee_view), # 127.0.0.1/coffee/
for 구문으로 만들어보자.
<!DOCTYPE html>
</html>
<head>
<title>Coffee List</title>
</head>
<body>
<h1>My Coffee List</h1>
{% for coffee in coffee_list %}
<p>{{ coffee.name }} , {{ coffee.price }}</p>
{% endfor %}
</body>
</html>
homepage에 forms.py를 만들어준다.
from django import forms # form import
from .models import Coffee # Model 호출
class CoffeeForm(forms.ModelForm): # ModelForm을 상속받는 CoffeeForm
# 구글의 form을 작성하는 것과 유사
class Meta: #form을 만들기 위해서 어떤 form을 써야하는지
model = Coffee
fields = ('name', 'price', 'is_ice')
# 추가
from .forms import CoffeeForm
# 수정
def coffee_view(request):
coffee_all = Coffee.objects.all()
form = CoffeeForm() # Form의 객체를 만들어 준다.
return render(request, 'coffee.html',{"coffee_list":coffee_all})
<!DOCTYPE html>
</html>
<head>
<title>Coffee List</title>
</head>
<body>
<h1>My Coffee List</h1>
{% for coffee in coffee_list %}
<p>{{ coffee.name }} , {{ coffee.price }}</p>
{% endfor %}
<form>
{{ coffee_form.as_p }} #정확한 form의 형태로 만들어주기 위해서 as_p 우리가 평소보던 form의 형태로
</form>
</body>
</html>
form의 틀만 만들었을뿐 form의 정보를 서버에 전송하는 버튼이 없다.
<form method="POST">
{{ coffee_form.as_p }}
<button> type="submit">Save</button>
</form>
form에 대한 보안처리를 위해 CSRF토큰을 넣어줘야 한다.
<form method="POST">
{% csrf_token %} {{ coffee_form.as_p }}
<button type="submit">Save</button>
</form>
하지만 정보가 전달이 되었을뿐 DB에는 들어가 않았다. view에는 post를 처리하는 정보가 담겨 있지 않기 때문이다.
def coffee_view(request):
coffee_all = Coffee.objects.all()
# 만약 request가 POST라면:
# POST를 바탕으로 form을 완성하고
# form이 유효하면 -> 저장
if request.method == "POST":
form = CoffeeForm(request.POST) # 완성된 form을 만들고
if form.is_valid(): # 유효하다면
form.save() # 저장
form= CoffeeForm()
return render(request, 'coffee.html',{"coffee_list":coffee_all, "coffee_form":form})
form은 양식을 받기위한 양식이다. 어떤 모델을 어떤 field에서 만들지는 view단에서 instance화해서 template에 전달하고 이렇게 하면 admin을 거치지 않고도 DB에 접근이 가능하다.
#urls.py
from homepage.views import coffee_view
from homepage.views import coffee_update
from homepage.views import coffee_delete
urlpatterns = [
path('', index), # 127.0.0.8000/일때 index를 실행하라
path('coffees/',coffee_view), # 127.0.0.8000/coffee/
path('coffees/update/<int:pk>',coffee_update),
path('coffees/delete/<int:pk>/',coffee_delete),
path('admin/', admin.site.urls), # 127.0.0.8000/admin/
]
#views.py
from django.shortcuts import HttpResponse, render, get_object_or_404
from .models import Coffee
from .forms import CoffeeForm
def coffee_view(request):
coffee_all = Coffee.objects.all()
# 만약 request가 POST라면:
# POST를 바탕으로 form을 완성하고
# form이 유효하면 -> 저장
if request.method == "POST":
form = CoffeeForm(request.POST) # 완성된 form을 만들고
if form.is_valid(): # 유효하다면
form.save() # 저장
form= CoffeeForm()
return render(request, 'coffee.html',{"coffee_list":coffee_all, "coffee_form":form})
def coffee_update(request, pk):
coffee = get_object_or_404(Coffee, pk=pk)
if request.method == "POST":
form = CoffeeForm(request.POST, instance = coffee)
if form.is_valid():
form.save()
form= CoffeeForm()
return render(request, 'coffee_update.html', {"coffee_form":form})
def coffee_delete(request, pk):
coffee = Coffee.objects.get(pk=pk)
if request.method == "POST":
coffee.delete()
form= CoffeeForm()
return render(request, 'coffee_delete.html', {"coffee_form":form})
#coffee_update.html
<!DOCTYPE html>
<html>
<head>
<title>Coffee Update</title>
</head>
<body>
<h1>Update Coffee List</h1>
<form method="POST">
{% csrf_token %} {{ coffee_form.as_p }}
<button type="submit">수정하기</button>
</form>
</body>
</html>
#coffee_delet.html
<!DOCTYPE html>
<html>
<head>
<title>Coffee Update</title>
</head>
<body>
<h1>Delete Menu</h1>
<form method="POST">
{% csrf_token %}
<h2>이 메뉴를 삭제하시겠습니까?</h2>
<button type="submit">삭제하기</button>
</form>
</body>
</html>