반응형

참고

https://tutorial.djangogirls.org/ko/django_forms/


기존에 관리자 페이지로 들어가서 추가는 해보았지만 일반 사용자들도 글을 추가할 수 있는 페이지를 만들 필요가 있습니다.

django에서는 데이터베이스를 추가 삭제 수정할때도 직접 쿼리문을 작성하지 않아도 되도록

form을 제공해줍니다.

장고폼을 사용해 봅시다!




blog디렉토리안에 파일을 만듭니다.


blog/forms.py생성

1
2
3
4
5
6
7
8
9
from django import forms
 
from .models import Post
 
class PostForm(forms.ModelForm):
 
    class Meta:
        model = Post
        fields = ('title''text',)
cs


코드를 살펴봅시다 .

django의 forms을 사용하기위해 import해주고 사용할 모델을 import 해주어야 합니다.

그리고 폼을 생성해줄 클래스를 만들어줍니다.인자로 ModelForm이라는것을 알려줍니다.


class Meta는 어떤 model이 쓰여야 하는지 알려주는 장고에게 알려주는 구문입니다.

fields는 받아올 필드를 지정해줍니다. author와 create_date는 사용자에게 받을 필요가 없기때문에 넣지 않습니다.


이제 이전 글에서 새페이지를 만들었던것처럼 추가해 봅시다.




새글 생성페이지 추가해보기


생성순서

templates->view->models->views->templates


blog/templates/blog/base.html을 수정(페이지 헤더부분에 새 글 작성하기 페이지로 이동할 링크와 버튼 생성)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{% load static %}
<html>
    <head>
        <title>Django blog</title>
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
        <link href='//fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
        <link rel="stylesheet" href="{% static 'css/blog.css' %}">
    </head>
    <body>
        <div class="page-header">
            <a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
            <h1><a href="/">Django Girls Blog</a></h1>
        </div>
        <div class="content container">
            <div class="row">
                <div class="col-md-8">
                    {% block content %}
                    {% endblock %}
                </div>
            </div>
        </div>
    </body>
</html>

cs


추가된부분

1
2
3
4
<div class="page-header">
            <a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
            <h1><a href="/">Django Girls Blog</a></h1>
</div>

cs




blog/urls.py 수정(view에서 url패턴 만들기)


1
2
3
4
5
6
7
8
from django.urls import path 
from . import views
 
urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
    path('post/new/', views.post_new, name='post_new'),
]

cs


post_new라는 요청을 받으면 post/new/ 링크로 이동하도록 만들고 views.post_new를 통해 html을 연결합니다.



blog/views.py 수정(view에서 model을 받아 template으로 이동)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from django.shortcuts import render, get_object_or_404
from .models import Post
from .forms import PostForm
 
 
def post_list(request):
    posts = Post.objects.all()
    return render(request, 'blog/post_list.html', {'posts': posts})
 
 
def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'blog/post_detail.html', {'post': post})
 
 
def post_new(request):
    form = PostForm()
    return render(request, 'blog/post_edit.html', {'form': form})
cs


PostForm과 post_new함수를 추가해 줍니다.

PostForm을 호출하여 템플릿(html)로 넘겨줍니다.



blog/templates/blog/post_edit.html 생성(view->template)

1
2
3
4
5
6
7
8
9
{% 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 %}

cs


{% csrf_token %}은 보안을 위한 구분입니다. CSRF 공격을 token검증을 통해 막아줍니다.

CSRF(Cross Site Request Forgery) 란?

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


{{ form.as_p }}은 간단한 페이지(html)을 자동으로 만드는 구문입니다.


다시 views.py에서 이부분을 구현해 줍니다.


blog/views.py수정(template->view로 데이터 받기)

-import 추가

1
2
from django.shortcuts import render, get_object_or_404,redirect
from django.utils import timezone
cs

-post_new 함수 수정

1
2
3
4
5
6
7
8
9
10
11
12
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})
cs

 

POST로 데이터를 받았을만 동작 할 수 있도록 만들어줍니다.

받은데이터로 post객체(새글)를 만들어 저장한 후 작성한 글을 확인할수 있게 post_detail로 넘겨줍니다.


폼 검증하기

장고 폼은 각 데이터들의 유효성 검사를 쉽게 해결해준다.

직접 구현할려면 많은 예외사항을 다 처리해주어야 한다.

어떻게 처리하는지 새글을 작성할때 title과 text를 비우고 save를 눌러보자



글수정 페이지 만들기


글 수정은 상세페이지에 있도록 만들어 줍니다. 앞서 페이지를 추가하던 순서대로 진행해줍니다.post_detail.html에 수정버튼과 링크를 추가해줍니다. 글 수정 페이지는 새글 작성 페이지의

html을 사용하기 때문에 수정페이지를 따로 만들지는 않습니다 .


blog/templates/blog/post_detail.html 에 추가

1
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"></span></a>
cs


<h1>{{ post.title }}</h1> 위에 추가해 줍니다.



blog/urls.py 에 추가

1
 path('post/<int:pk>/edit/', views.post_edit, name='post_edit')
cs


blog/views.py 에 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
def post_edit(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = PostForm(request.POST, 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})
cs



post_new함수와 거의 비슷하지만 pk를 받아와 처리하는 모습을 볼수있다.

또 해당글의 instance(수정전 데이터)를 가져와서 post_edit.html로 전달해줍니다.

else밑이 수정전 데이터를 불러오는곳입니다.


사실 수정,삭제는 글쓴이만 할수 있게 만들어야 한다.

로그인기능을 만들고 구현해 볼 예정이다

반응형

'웹개발 > Django' 카테고리의 다른 글

Django 페이징 #11  (0) 2020.12.20
Django 네비게이션바 #10  (0) 2020.12.14
Django 다른페이지 추가해보기 #8  (0) 2020.12.13
Django 웹디자인(CSS) #7  (0) 2020.12.13
Django 템플릿 동적데이터 #6  (0) 2020.12.13
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기