Django 05 - CRUD 2 (Create & Read)
27 Apr 2019 | DjangoModel을 활용한 CRUD 구현 (2)
Create (Create 페이지 구현)
#views.py
from django.shortcuts import render
from .models import Post
def new(request):
return render(request, 'new.html')
def create(request):
title = request.GET.get('title')
content = request.GET.get('content')
post = Post(title=title, content=content)
post.save()
return render(request, 'create.html')
#urls.py
from posts import views
urlpatterns = [
path('create/', views.create),
path('new/', views.new),
]
<-- new.html -->
<body>
<form action="/posts/create/", method="get">
<input type="text" name="title"/>
<input type="text" name="content"/>
<input type="submit" value="Submit"/>
</form>
</body>
<-- create.html -->
<body>
<h1> 성공적으로 Post를 생성 했습니다! </h1>
</body>
views.py에서render함수로new.html을 호출함.-
input 태그를 통해 들어오는 값은 총 2가지로, 각각
title과content라는name의 속성으로 정의 되어 있다. 여기서Dict의 구조를 띔. {title: 사용자 입력 값, content: 사용자 입력값} views.py안create함수에서Dict에서 저장된 value값을 가져와 각각title과content라는 변수에 저장.
title = request.GET.get('title')
content = request.GET.get('content')
- 데이터베이스에 내용을 저장하는 코드를 작성함. 아래의 경우, Post 클래스를 사용하기 위해
models.py에 작성된 Post 클래스를import를 해와야함.
from .models import Post
post = Post(title=title, content=content)
post.save()
- 최종적으로,
new.html에서 사용자가 내용을 입력하면,form태그action속성으로 연결된create.html으로 이동되어,views.py에 정의된create함수가 실행된다. - 해당 함수에 정의된 변수명에 따라, 데이터베이스에 내용이 저장되며, 사용자는
create.html에 따라, “성공적으로 Post되었습니다” 라는 결과를 화면을 보게 된다.
URL 구조 변경
지금까지 우리는 프로젝트 폴더 내에 존재하는 urls.py (어플리케이션 폴더의 상위디렉토리)에 모든 url을 저장해왔다. 그런데 만약, 한 프로젝트 내에 무수히 많은 어플리케이션을 생성하고, 관련 url을 urls.py에 작성한다면, traceability 적인 측면 뿐만 아니라 직관적으로 각 어플리케이션에 해당하는 url을 구분하기 힘들 것이다.
따라서, urls.py를 각 어플리케이션 내에 새로 생성하여, 손쉽게 urls.py를 관리 할 수 있도록 해보자.
- 어플리케이션 내에 urls.py 작성
from django.urls import path
from . import views
#현재 디렉토리 내에 views.py를 불러오므로 from 에는 현재 디렉토리를 의미하는 . 을 써줌.
urlpatterns = [
path('create/', views.create),
path('new/', views.new),
]
#일반적인 작성방법대로, urlpatterns을 작성한다.
- 상위 디렉토리(프로젝트 폴더) 내 urls.py 수정
from django.urls import path, include
urlpatterns = [
path('posts/', include('posts.urls')),
path('admin/', admin.site.urls),
]
path의 첫 번째 인수로, 'posts/' 값을 줌에 따라, posts(어플리케이션)에 적용되는 모든 url을 직관적으로 이해할 수있음. 또한 두번째 인수로, include('posts.urls') 을 주어, posts(어플리케이션) 내 urls.py와 연결을 시켰음. 이 때, 외장 함수인 include를 import 하였음.
Read (1) - 리스트 페이지 구현
- views.py
- 모델
Post내 DB에 저장된 모든 값을 불러오는objects.all()을 입력한 후,posts변수에 저장 - 해당 변수를 템플릿 변수로 index.html으로 함께 넘김
- 모델
#views.py
def index(request):
#데이터 베이스에 저장된 모든 값을 불러옴.
posts = Post.objects.all()
return render(request, 'index.html', {'posts':posts})
#urls.py
urlpatterns = [
path('', views.index),
]
- index.html
- 템플릿 변수로 넘어간
posts를 진자템플릿을 사옹하여 반복문을 돌림 - 반복문 안에서, 객체의 멤버변수인
.title과.content를 진자템플릿을 불러옴.
- 템플릿 변수로 넘어간
<body>
<h1>Post Index</h1>
<ul>
<-- 반복문을 돌리기 위해 jinja 템플릿 사용 -->
</ul>
</body>
Read (2) - 디테일 페이지 구현
우리가 작성한
index.html은 데이터베이스에 입력한 레코드 전체에 대한 정보를 보여줬음. 이제, 게시판 안의 글의 내용을 보는 것과 같이, 클릭하여 들어가서 세부 내용을 보여주는 페이지를 생성해보자.레코드에 대한 세부 정보를 보여주기 위해서는, 각 레코드가 갖고 있는 고유값(id; pk)로 접근을 해야 함. 이를 위해 id값을 파라미터로 갖고오는 Variable routing을 설정 해야 함.
예) 기본주소/posts/1
- views.py & urls.py
detail함수의 두번째 파라미터인post_id는 레코드의 고유키를 의미하는 variable routing임. 이는urls.py내path함수의 첫번째 인자와 반드시 일치 시켜줘야함.post = Post.objects.get(pk=post_id):Post라는 모델 클래스를 통해 저장된 1번(pk=1) 레코드를post라는 변수로 저장함. 이때post는Post클래스의 인스턴스라고 볼 수 있음.‘post’를 템플릿 변수로 지정하였으며, 사용자의 편의상, Dict의 key값와 value값을post로 일치시켰음. 따라서,detail.html에서 템플릿 변수post를 입력하면,Post의 인스턴스이자, 템플릿 변수의 key값인post가 호출 됨.
#views.py
def detail(request, post_id):
post = Post.objects.get(pk=post_id)
return render(request, 'detail.html', {'post':post})
#urls.py
urlpatterns = [
path('<int:post_id>/', views.detail),
]
- detail.html
- 위의 설명에 이어,
Post의 인스턴스인post는 클래스에서 정의된 멤버 변수(예,post.title/post.content)를 불러올 수 있음. - 추가로, 레코드 전체에 대한 정보가 담겨 있는
기본주소/posts/ 또는 (index.html)으로 돌아가기 버튼을 만들기 위해, a 태그를 사용 하였음.
- 위의 설명에 이어,
<body>
<h1>Post Detail</h1>
<h2>Title : </h2>
<p> Content : </p>
<a href="/posts/">List</a>
</body>
Comments