Form
블로그 글을 추가하거나 수정 기능
폼(양식, forms) 으로 강력한 인터페이스를 만들 수 있다.
장고 폼이 좋은 이유는 아무런 준비 없어도 양식을 만들 수 있고, ModelForm을 생성해 자동으로 모델을 결과물에 저장할 수 있다는 것이다.
-폼을 하나 만들어서 Post 모델에 적용해보자
-forms.py 라는 파일을 만든다.
-blog/forms.py
from django import forms # blog/forms 를 import 한다
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
field = ('title', 'text',)
class Meta : 폼을 만들기 위해서 어떤 model이 쓰여야 하는지 장고에 알려주는 구문이다. (model = Post)
이제 뷰에서 이 폼을 사용해 템플릿에서 보여주기만 하면 된다.
다음에는 링크, URL, 뷰 그리고 템플릿을 만들어보겠다.
URL
url(r'^post/new/$', views.post_new, name='post_new')
#post에 new라는 주소로 들어오게되면 views.post_new 뷰를 호출할 것이고, 이 패턴의 이름은 post_new 이다.
하지만 views.post_new 라는 view를 생성해주지 않았기 때문에 views.py에 가서
#views.py
from .forms import PostForm
def post_new(request):
form = PostFrom()
return render(request, 'blog/post_edit.html', {
'form' : form,
})
http://127.0.0.1:8000/post/new/ 에 접속해도 post_new안에 아무것도 정의하지 않았기 때문에 오류 페이지가 뜬다.
post_edit.html 작성
{% extends "blog/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-primary">Save</button>
</form>
{% endblock %}
class="save btn btn-primary" 부분을 default로도 변경할 수 있다.
django form 에서 기본적인 틀을 제공해주는거 같다.
Form과 페이지링크
<a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
+버튼을 누르면
[01/Jul/2019 16:33:30] "GET /post/new/ HTTP/1.1" 200 1378
위에서 댓글을 작성해서 SAVE 버튼을 누르면
[01/Jul/2019 16:33:31] "POST /post/new/ HTTP/1.1" 200 1378
POST로 /post/new/ 로 데이터를 보낸다. 보내면 views.py 로 이동하게 된다.
게시글 업로드나 파일 업로드를 하면 request.POST 와 request.FILES에 데이터가 담겨 전송되게 된다.
끝으로, 새 블로그 글을 작성한 다음에 post_detail 페이지로 이동하게 끔 만들어보자.
#views.py
# request.POST, request.FILES
if request.method == 'POST': # 현재 요청이 POST라면
form = PostForm(request.POST, request.FILES) # PostForm을 생성할 때 POST와 FILES에서 값을 가져와서 Form 생성
if form.is_valid(): # 유효성 검사 빠진 값은 없는지 등등 # 실패하게되면 form에서 오류를 갖고 있게 된다.
post = form.save(commit=False) # commit=False 란 넘겨진 데이터를 바로 Post모델에 저장하지 말라는 뜻이다.
# 왜냐하면 작성자를 추가한 다음 저장해야되니까 그렇다. 대부분의 경우에는 commit=False를 쓰지 않고 바로
# form.save()를 사용해서 저장한다. 하지만 여기서는 작성자 정보를 추가하고 저장해야 하므로 commit=False
# 를 사용하는 것이다.
post.author = request.user
post.published_date = timezone.now()
post.save() # 변경사항(작성자 정보를 포함)을 유지할 것이고 새 블로그 글이 만들어질 것이다.
return redirect('post_detail', post.pk)
else:
from = PostForm() # 빈 폼
하지만 /admin 에서 로그아웃이 되고, 새로운 글을 작성해서 넣으려고하면 오류가 발생한다.
해당 오류는 post.author = request.user 에서 발생한다. 왜냐하면 비인증 상태이기 때문에 그렇다.
request.user 로그인 유저 정보를 가져오는 것인데 로그아웃 되어있기 때문에 비인증 유저 정보가 가져와졌기 때문에
오류가 발생한다.
폼 수정하기(post_edit)
# post_detail.html
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
#버튼 추가
#views.py
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_edit.html', {
})
#post_edit 생성
#urls.py
url(r'^post/(?P<pk>\d+)/edit/$', views.post_edit, name='post_edit'),
#url 추가 ex) http://127.0.0.1:8000/post/15/edit/
#views.py
#post_new 의 if구문을 가져와서 붙여넣기 한 뒤 instance=post를 form = PostForm() 안에 추가
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == 'POST':
form = PostForm(request.POST, request.FILES, 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', post.pk)
else:
form = PostForm(instance=post) #
return render(request, 'blog/post_edit.html', {
'form': form #
})
보안
로그인한 유저만 글 작성이 가능하게 만들고 싶다.
+버튼을 로그인한 유저만 보이게 하고 싶다.
{% if user.is_authenticated %} # 현재 유저가 login이 되어있다면 보여주겠다.
<a href="{% url 'post_new' %}" class="top-menu">
<span class="glyphicon glyphicon-plus"></span>
</a>
{% endif%}
하지만 url 을 안다면 로그인을 하지 않아도 접속할 수 있다. 그걸 방지하기 위해서는
@login_required 를 해주면 된다. 하지만 너무 심화과정이기 때문에 나중에 보도록 하자.
'Web > Django' 카테고리의 다른 글
Django / 복습(실습) (0) | 2019.07.03 |
---|---|
Django / 복습 (0) | 2019.07.01 |
Django / 프로그램 애플리케이션 확장 (0) | 2019.06.30 |
Django / 템플릿 동적 데이터와 쿼리셋 (0) | 2019.06.30 |
Django / 데이터 추가/수정/삭제 / HTML / ORM(정규표현식) / 쿼리셋 (0) | 2019.06.29 |
댓글