DevHyun

[DevHyun's Blog] Django Form 만들기(일반 사용자가 Post 추가 가능하게 만들기) 본문

Web/Django&Python Blog Projecct

[DevHyun's Blog] Django Form 만들기(일반 사용자가 Post 추가 가능하게 만들기)

D3V3L0P3R 2020. 10. 21. 19:09

장고걸스 코치들과 자원봉사자들의 수고로 번역된 글을 참고하였습니다.

tutorial.djangogirls.org/ko

 

Django Form은 ModelForm을 생성해 자동으로 모델에 결과물을 저장할 수 있습니다.

 

∨ form 관련 참고 사이트

junlab.tistory.com/193

wayhome25.github.io/django/2017/05/06/django-model-form/

 

1. Blog 디렉토리에 from.py 만들기

 

2. Model Form 생성

* Blog/forms.py

* Form (일반 폼) : 직접 필드 정의, 위젯 설정이 필요

* Model Form (모델 폼) : 모델과 필드를 지정하면 모델폼이 자동으로 폼 필드를 생성

 

from django import forms

from .models import Post

class PostForm(forms.ModelForm):

    class Meta:
        model = Post
        fields = ('title', 'text',)

* forms import

* Post model Import

* PostForm(form 이름) 선언

* class Meta : 이 폼(PostForm)을 만들기 위해서 어떤 model이 쓰여야 하는지 Django에 알려주는 구문

 

3. form과 url 링크

* Blog/templates/Blog/base.html 

...
..
.
        <div class="page-header">
            <a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
            <h1><a href="/">DevHyun's Blog</a></h1>
        </div>
...
..
.

 

4. Run -> NoReverseMatch Error 발생

 

5. Blog/views.py에 Post_new 선언

* Blog/views.py

* Post_new Form을 추가하기 위해 PostForm() 함수를 호출하도록 하여 템플릿에 넘깁니다.

...
..
.
from .forms import PostForm

...
..
.

def post_new(request):
    form = PostForm()
    return render(request, 'blog/post_edit.html', {'form': form})

 

6. Blog/urls.py에 Post_new 추가

* Blog/urls.py

 

...
..
.
urlpatterns = [
...
..
.
    path('post/new/', views.post_new, name='post_new'),
]

 

7. Run -> TemplateDoesNotExist at /post/new/ Error 발생

 

8. Blog/templates/Blog 디렉토리에 post_edit.html 작성하기

* Blog/templates/Blog/post_edit.html  

 

{% extends 'blog/base.html' %}

{% block content %}
    <h1>New post</h1>
    <form method="POST" class="post-form">
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Save</button>
    </form>
{% endblock %}

* {{ form.as_p }} : form 보이게하기 ( {{ Post.title}}와 비슷)

 

9. Run-> 페이지 오른쪽 상단에 +버튼 추가 -> 클릭 -> new Post 작성 -> Save -> forbidden 403 Error 발생

 

10. Blog/templates/Blog/post_edit.html에서 form tag에 {% csrf_token %} 추가

* Blog/templates/Blog/post_edit.html 

* {% csrf_token %} : CSRF공격에 대한 방어

* CSRF(Cross Site Request Forgery)

: 웹사이트 취약점 공격의 하나로, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)

를 특정 웹사이트에 요청하게 하는 공격입니다. 이미 사용자가 접속한 상황에서 요청값을 조작하여 사용자가 원하지 않는 action을 보내 웹 어플리케이션을 악용하합니다. 그리고 사용자의 권한에 따라 위험성이 달라집니다.

 

참고 사이트

chagokx2.tistory.com/49

 

 

[Django Basic 09] {% csrf_token %}

1. CSRF(Cross Site Request Forgery) : 웹사이트 취약점 공격의 하나로, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등) 를 특정 웹사이트에 요청하게 하는 공격 이미 사용

chagokx2.tistory.com

{% 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-default">Save</button>
    </form>
{% endblock %}

 

11. Run-> 페이지 오른쪽 상단에 +버튼 추가 -> 클릭 -> new Post 작성 -> Save -> 반응이 없고 Post된 글 확인 불가

 

12. views.py에서 두가지 상황으로 나누어 처리(if문 사용)

* Blog/views.py

* 첫 번째: 폼에 입력된 데이터를 view 페이지로 가지고 올 때.

* 두 번째: 처음 페이지에 접속했을 때. (새 글을 쓸 수 있게 폼이 비어있어야)

...
..
.
def post_new(request):
    form = PostForm()
    return render(request, 'blog/post_edit.html', {'form': form})

...
..
.

from django.shortcuts import redirect
...
..
.

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})


* 첫번째 if : 요청받은 method가 Post 라면 field 값들을 request.Post에 저장!

* 두번째 if 

- is_valid()

: is_valid() 함수는 입력받은 폼의 대한 유효성 검사를 실행. is_valid() 함수가 호출되면 값이 유효하다면 참이 리턴되고 cleaned_data에 값이 저장.

- post = form.save(commit = false)

: Model Form 클래스에는 .save(self, commit=True) 메소드가 구현되 었음

: DB 저장 여부를 commit flag를 통해서 결정

: commit=False flag를 통해 함수 호출을 지연

: commit = false를 사용한 이유 -> PostForm에는 작성자(author) 필드가 없지만,  Post시 필드 값이 필요!

- return redirect('post_detail', pk= post.pk)

: 새로 작성한 post의 pk를 post_detail view로 전송!

* else : 처음 페이지에 접속했을 때 폼 비우기

 

13. Run -> Post 입력 해보기! 성공!!

 

 

- 다음 실습 링크!

d3v3lop3r.tistory.com/25?category=816261

 

Django Form 만들기(일반 사용자가 Post 수정 가능하게 만들기)

Django Form 만들기(일반 사용자가 Post 추가 가능하게 만들기) 에서 이어집니다. d3v3lop3r.tistory.com/24 Django Form 만들기(일반 사용자가 Post 추가 가능하게 만들기) 장고걸스 코치들과 자원봉사자들의 수

d3v3lop3r.tistory.com

 

Comments