Form을 이용하면 글을 Create, Update, Delete가 가능하다.
Create와 Update를 해보자.
Form 위치
blog (StartApp)
└─── forms.py
1. CREATE [폼 추가하기]
Form 작성
장고에서 제공해주는 Form인 ModelForm을 이용했다.
blog/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text',)
Meta는 이 Form을 만들기 위해 어떤 model이 쓰여야 하는지 장고에 알려주는 구문이다.
fields에는 보여지게 할 필드를 넣는다.
(author필드, created_date필드, published_date필드는 유저가 직접 입력하는 부분이 아니기 때문에 넣지 않는다.)
form과 페이지 링크
base.html에서 플러스 버튼을 누르면 새 글을 추가할 수 있게 해보자.
blog/templates/base.html
<a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
부트스트랩 테마에 있는 glyphicon 클래스로 더하기 기호가 보이게 된다.
blog/urls.py
path('post/new', views.post_new, name='post_new'),
blog/views.py
def post_new(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
forms.py에서 만든 폼을 불러온다.
HTML에서 <form>정의에 method="POST"라는 속성이 있었다.
따라서 POST로 넘겨진 폼 필드의 값들은 request.POST에 저장된다.
view는 두 상황으로 나누어 처리할 수 있다.
1. 처음 페이지에 접속했을 때
우리가 새 글을 쓸 수 있게 폼이 비어있어야한다.
2. 폼에 입력된 데이터를 view 페이지로 가지고 올 때
method가 POST라면 폼에서 받은 데이터를 PostForm으로 넘겨주면 된다.
그러곤 바로 저장하는 게 아니다. 아래 부분을 보자.
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
먼저, is_valid()로 폼에 입력된 값이 올바른지 확인해야 한다.
다음 작업은 일반적으로 두 단계로 나눌 수 있다.
1. form.save()로 폼을 저장하는 작업
2. author 필드, published_date 필드를 추가하는 작업
PostForm에는 author필드, published_date 필드가 없다.
따라서 commit=False로 데이터를 바로 Post 모델에 저장하지 않게 한다.
그리고 빈 필드를 채운다. 이제 저장한다.
redirect를 이용하면 지정한 페이지로 이동한다.
blog/templates/post_edit.html
{% extends 'base.html' %}
{% block content %}
<h1>New post</h1>
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
{% endblock %}
1. {{ forms.as_p }}로 폼이 보이게 한다.
2. HTML 태그로 폼을 감싼다. <form method="POST"> ... </form>
3. HTML로 save 버튼을 만든다.
4. 마지막으로 <form ...>을 열어서 {% csrf_token %}을 추가한다. (폼 보안을 위해서)
2. UPDATE [폼 수정하기]
디데일 페이지에서 수정하기 버튼을 눌러 글을 수정할 수 있게 하자.
blog/templates/post_detail.html
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
post_detail.html에 위 코드를 추가한다.
blog/urls.py
path('post/<int:pk>/edit/', views.post_edit, name='post_edit'),
ursl.py에 위 코드를 추가한다.
blog/views.py
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form})
post_new 함수와 비슷해 보인다. 하지만 완전히 같지는 않다.
다른 점
1. pk를 매개변수로 받는다.
2. get_object_or_404를 호출하여 수정하고자 하는 글의 Post 모델을 instance로 가져온다.
이렇게 가져온 데이터를 폼을 만들 때와 폼을 저장할 때 사용하게 된다.
결과
보안
아래 조건문을 추가하면 로그인하지 않은 유저는 글 추가 버튼이 보이지 않는다.
blog/templates/base.html
{% if user.is_authenticated %}
<a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
{% endif %}
'BACK-END > Django' 카테고리의 다른 글
[Django][장고걸스][ubuntu] Django ORM과 쿼리셋[Querysets] (0) | 2022.01.12 |
---|---|
[Django][장고걸스][ubuntu] Django HTML (0) | 2022.01.12 |
[Django][장고걸스][ubuntu] Django urls (0) | 2022.01.12 |
[Django] 데이터베이스 초기화 (0) | 2022.01.12 |
[Django][장고걸스][ubuntu] Git 설치하기, 저장소 만들기 (0) | 2022.01.06 |