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