일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 장고유저모델
- 장고
- 쿼리셋
- namespace
- 장고수정기능
- 템플릿태그
- 랜덤번호
- 웹페이지제작
- 장고로그인회원가입
- 검색기능
- extends
- CRUD
- 템플릿상속
- modelform
- path converter
- detail page 만들기
- 파이썬
- Python
- 템플릿변수
- django
- 템플릿필터
- 장고어드민
- DjangoModel
- DjangoAdmin
- get object or 404
- 글쓰기기능
- 장고모델
- DjangoUsers
- queryset
- 모델폼
- Today
- Total
하루에는
[Django]장고 모델폼 ModelForm을 사용한 CRUD 구현 본문
Overviews
- Model Form 사용
- post 앱의 CRUD 구현
지금 post앱의 새 글 쓰기는 admin 페이지에서만 가능합니다. 웹에서도 CRUD가 가능하게 해보겠습니다.
1. (비추천)입력 받을 필드들을 input 태그를 써서 만드는 방법
<form method='POST'>
{% csrf_token %}
<input type='text' name='title'/>
<textarea name='content'/>
<input type='submit' value='등록'/>
</form>
2. (추천)저장할 필드들을 파이썬 파일에 작성하고, 파일을 {{form}}에 담아서 불러오기만 하는 방법
<form method='POST'>
{% csrf_token %}
{{form}}
<input type='submit' value='등록'/>
</form>
Model Form
- 모델에서 정의한 필드대로 form을 자동으로 만들어 줌
- app에 forms.py를 만들고, 어떤 필드를 입력받을지 정한다.
- 사용자로부터 데이터를 입력받아서 저장할 때는 대부분 모델폼을 사용
- 모델폼의 장점
- 폼을 위한 HTML을 작성할 필요 없음
- 데이터 유효성 자동으로 검사
- 올바르지 않은 데이터를 입력했을 경우 에러메시지와 함께 사용자에게 알려줌
- 재사용 가능
Create
post 앱에 forms.py를 만듭니다.
그리고 내용을 작성합니다.
# post/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title','content']
- from django import forms : 장고에서 제공하는 forms 기능을 사용하기 위해 임포트
- from .models import Post : Post 모델을 사용하기 위해 임포트
- class PostForm(forms.ModelForm) : PostForm이라는 이름의 모델폼 클래스 생성
- model = Post : form에서 사용할 모델이 Post임을 명시
- fields : Post 모델에서 입력받고 싶은 필드를 리스트 형태로 작성. 'all' 이라고 작성하면 전체 필드를 추가함.
url 설정
글 작성을 위해서는 두 가지 path가 필요합니다.
-
글 작성 화면, 즉 form을 띄울 화면(new)
-
실제 create를 진행하는 메서드(postcreate)
from django.urls import path
from . import views
urlpatterns = [
path('list/', views.postlist, name='postlist'),
path('show/<int:post_id>', views.show, name='show'),
path('new/', views.new, name='new'), # 추가
path('postcreate/', views.postcreate, name='postcreate'), # 추가
]
View 설정
post의 views.py에 new와 postcreate를 추가합니다.
from django.shortcuts import render, get_object_or_404, redirect # 추가
from .models import Post
from .forms import PostForm # 추가
from datetime import datetime # 추가
# Create your views here.
def postlist(request):
...
def show(request, post_id):
...
def new(request):
return render(request, 'new.html')
def postcreate(request):
if request.method == 'POST': # POST 방식으로 요청이 들어왔을 때
form = PostForm(request.POST) # 입력된 내용들을 form이라는 변수에 저장
if form.is_valid(): # form이 유효하다면(models.py에서 정의한 필드에 적합하다면)
post = form.save(commit=False) # form 데이터를 가져온다.
post.created_at = datetime.now()
post.save() # form 데이터를 DB에 저장한다.
return redirect('postlist')
else:
return redirect('postlist')
else: # GET 방식으로 요청이 들어왔을 때
form = PostForm()
return render(request, 'new.html', {'form': form})
- redirect, PostForm 임포트
- postcreate
- 요청이 POST로 들어왔을 경우 : 입력받은 내용의 유효성을 검사하고 저장
- 요청이 GET으로 들어왔을 경우 : PostForm을 form이라는 변수에 담아서 new.html을 렌더링
Template 설정
post/templates에 new.html을 만들고 내용을 작성합니다.
<h3>글 쓰기</h3>
<form method='POST'>
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" value="등록">
</form>
- {{form.as_table}} : form을 table 형식으로 출력. 그냥 {{form}}으로 써도 무방함. {{form.as_p}}는 p태그 형식으로 출력함
postlist.html에 글 작성하기 링크를 추가하고 서버를 돌려봤습니다.
DateTimeField에 auto_now_add=True를 추가하면 객체가 생성된 시각이 자동으로 저장됩니다.
그러면 아래와 같이 현재 시각을 따로 저장해주는 과정을 생략할 수 있습니다.
from django.shortcuts import render, get_object_or_404, redirect # 추가
from .models import Post
from .forms import PostForm # 추가
from datetime import datetime # 추가
# Create your views here.
def postlist(request):
...
def show(request, post_id):
...
def new(request):
return render(request, 'new.html')
def postcreate(request):
if request.method == 'POST': # POST 방식으로 요청이 들어왔을 때
form = PostForm(request.POST) # 입력된 내용들을 form이라는 변수에 저장
if form.is_valid(): # form이 유효하다면(models.py에서 정의한 필드에 적합하다면)
post = form.save(commit=False) # form 데이터를 가져온다.
post.created_at = datetime.now()
post.save() # form 데이터를 DB에 저장한다.
return redirect('postlist')
else:
return redirect('postlist')
else: # GET 방식으로 요청이 들어왔을 때
form = PostForm()
return render(request, 'new.html', {'form': form})
Update
모델을 조금 수정하고 시작하겠습니다.
from django.shortcuts import render, get_object_or_404, redirect # 추가
from .models import Post
from .forms import PostForm # 추가
from datetime import datetime # 추가
# Create your views here.
def postlist(request):
...
def show(request, post_id):
...
def new(request):
return render(request, 'new.html')
def postcreate(request):
if request.method == 'POST': # POST 방식으로 요청이 들어왔을 때
form = PostForm(request.POST) # 입력된 내용들을 form이라는 변수에 저장
if form.is_valid(): # form이 유효하다면(models.py에서 정의한 필드에 적합하다면)
post = form.save(commit=False) # form 데이터를 가져온다.
post.created_at = datetime.now()
post.save() # form 데이터를 DB에 저장한다.
return redirect('postlist')
else:
return redirect('postlist')
else: # GET 방식으로 요청이 들어왔을 때
form = PostForm()
return render(request, 'new.html', {'form': form})
DateTimeField에 auto_now=True를 추가하면 객체가 수정된 시각이 자동으로 저장됩니다.
새 글 쓰기와 마찬가지로 forms.py를 사용해서 수정 화면을 만들겠습니다.
url 설정
글 쓰기와 마찬가지로 두 가지 path가 필요합니다.
-
글 수정 화면, 즉 form을 띄울 화면(edit)
-
실제 update를 진행하는 메서드(postupdate)
from django.urls import path
from . import views
urlpatterns = [
path('list/', views.postlist, name='postlist'),
path('show/<int:post_id>', views.show, name='show'),
path('new/', views.new, name='new'),
path('postcreate/', views.postcreate, name='postcreate'),
path('edit/', views.edit, name='edit'), # 추가
path('postupdate/<int:post_id>', views.postupdate, name='postupdate'), # 추가
]
- postupdate path는 어떤 post 객체를 수정할 지도 알아야 하기 때문에 path-converter가 필요합니다.
View 설정
post/views에 아래 코드를 추가합니다. 기존에 있던 코드들은 길어져서 생략했습니다.
def edit(request):
return render(request, 'edit.html')
def postupdate(request, post_id):
post = get_object_or_404(Post, pk=post_id)
if request.method == 'POST':
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect('show', post_id=post.pk)
else:
return redirect('postlist')
else:
form = PostForm(instance=post)
return render(request, 'edit.html', {'form': form})
- post = get_object_or_404(Post, pk=post_id) : path-converter로 받은 post_id로 수정하고자 하는 post 객체를 get
- POST로 요청이 들어왔을 경우
- form = PostForm(request.POST, instance=post) : PostForm의 인스턴스는 post임을 표시
- update 완료 후 해당 글의 상세 페이지로 리다이렉트
- GET으로 요청이 들어왔을 경우
- form = PostForm(instance=post) : post에 기존에 입력되어 있던 내용을 form에 담아서 edit.html을 렌더링
DateTimeField에 auto_now_add=True를 추가하면 객체가 생성된 시각이 자동으로 저장됩니다.
Template 설정
post/templates에 edit.html을 추가하고 내용을 작성합니다. new.html와 거의 동일합니다.
<h3>글 수정</h3>
<form method='POST'>
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" value="수정">
</form>
마지막으로 상세 페이지에 글 수정하기 링크를 추가하고 서버를 돌려봅니다.
Delete
delete는 path 하나만 있으면 됩니다.
from django.urls import path
from . import views
urlpatterns = [
path('list/', views.postlist, name='postlist'),
path('show/<int:post_id>', views.show, name='show'),
path('new/', views.new, name='new'),
path('postcreate/', views.postcreate, name='postcreate'),
path('edit/', views.edit, name='edit'),
path('postupdate/<int:post_id>/', views.postupdate, name='postupdate'),
path('postdelete/<int:post_id>/', views.postdelete, name='postdelete'), # 추가
]
- 어떤 post 객체를 삭제할지 지정해야 하기 때문에 역시 path-converter가 필요합니다.
View 설정
post/views.py에 코드를 추가합니다.
def postdelete(request, post_id):
post = get_object_or_404(Post, pk=post_id)
post.delete() # Post DB에서 post 객체 삭제
return redirect('postlist')
- path-converter로 보낸 post_id를 get
- 해당 post 객체를 삭제하고 postlist로 리다이렉트한다
Template 설정
삭제하기 코드를 임의로 만들었습니다.
'Python, Django' 카테고리의 다른 글
[Django]장고 Users(유저) 모델 (0) | 2019.12.10 |
---|---|
[Django]장고 템플릿 상속, url정리 네임스페이스 namespace (0) | 2019.11.29 |
[Django]장고 path-converter, get object or 404 장고로 게시물 상세페이지 만들기 (0) | 2019.11.28 |
[Django]장고 쿼리셋으로 검색기능 구현하기 (0) | 2019.11.28 |
[Django]장고 Model, admin, Queryset (0) | 2019.11.27 |