본문 바로가기

사이드 프로젝트/django

Django 로 게시판 만들기 3-2.게시글 작성 페이지 만들기

 

 

 [개발환경:ubuntu20.04 lts]

 

 

 

 

 

[django 관리자 아이디 패스워드 만들기]

 

 

장고는 이미 프로젝트를 생성할때부터 관리자에 대해 이용할수 있게끔 세팅되어있습니다.

 

settings.py에 들어가보면 admin이라는 app이 이미 설치되어있는 것을 볼 수 있습니다

 

 

Django Admin은 만든 프로젝트 웹사이트에서 페이지 관리 등을 할 수 있게끔 해줍니다.

 

 

 

아래와 같이  명령문으로 아이디를 만들어줍니다.

 

username(저는 admin이라고 했습니다.) 과 이메일(저는 패스했습니다. 엔터를 누르면 그냥 넘어갑니다.)

 

python manage.py createsuperuser

 

 

 

 

그리고 urls.py에 보면

url 설정전에 기본적으로 /admin으로 admin 설정은 되어있는것을 볼수 있습니다.

 

 

 로컬호스트/admin으로 들어가보면 이런 로그인 페이지가 나옵니다.

여기에 아까 만들었던 아이디와 패스워드를 치고 들어갑니다.

 

 

 

그러면 이런 관리페이지가 뜹니다.


 

[1,Forms]

 

Form은 사용자가 입력할때 필요한 양식입니다. 웹페이지에서 글을 쓰거나 할때 쓰는 것도 모두 form이라 할수 있습니다.

 

Form 처리과정은  어플리케이션 많은 레이어들이 상호작용하기 때문에 복잡합니다. 그리고 유효한 데이터를 입력받아야 하고

 

불필요한 데이터를 정리해줘야합니다. 그렇지 않으면 XSS공격과 SQL injection 공격에 노출될 수 있습니다

 

장고는 이러한 복잡한 과정을 Django Forms API를 통해 쉽게 만들어줍니다.

 

 

이런 형태의 form을 만들어 보겠습니다.

 

[2. url 설정]

makeBoards/urls.py를 아래와 같이 작성합니다.

그러면 http://127.0.0.1:8000/new/ 라는 주소로 글작성페이지를 설정해 줄 수 있습니다.

from django.contrib import admin
from django.urls import path

from boards1 import views #추가해주기

urlpatterns = [
     path('', views.home,name='home'),
     path('new/',views.new_topic,name='new_topic'),#게시글 작성 페이지 url 추가
     path('admin/', admin.site.urls),

]

 

 

[3.base.html수정]

 

앞으로 이 기본화면에 아래 내용 페이지를 이어받아  각각 구성한다고 생각하시면 됩니다.

 

즉 여러화면이 있을텐데 그 공통부분 요소를 만들어주는겁니다. 매번 작성하면 코드도 길어지고 유지보수에 불편하기 때문입니다.

 

 

{% load static %}<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test1</title>
    <link href="https://fonts.googleapis.com/css2?family=Nanum+Gothic:wght@700&display=swap" rel="stylesheet">


    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    
    <link rel="stylesheet" href="{% static 'css/app.css' %}">

</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <div class="container">
        <a class ="navbar-brand" href="{% url 'home' %}">장고 게시판</a>

    </div>
    </nav>
    
    <!-- 여기에 컨텐츠들을 계속 넣습니다.유지보수를 위해서 -->
    <div class="container"> 
        {% block content %}<!-- 이제 이부분에 content라는 이름으로 이어받아서 작성할수 있습니다. -->
        {% endblock %}
    </div>
 </body>


</html>

 

 

 

 

 

[4.view 설정]

우선 이 전에 만들었던 home함수에서 topics라는 객체를 추가해줍니다.

이후 게시글작성하고 models에 있는 객체를 가져오기 위함입니다.

 

#사용자정의
from django.contrib.auth.models import User
#장고의 사용자 모듈


# 장고의 view를 html문법으로 바꾸기 위한 렌더링모듈 과 new_topic view가 home으로 돌아가기 위한 redirect모듈
from django.shortcuts import render, redirect


from  .models import Topic, Reply
# 모델의 클래스명

from django.http import HttpResponse
#http 상태를 나타내기 위한 장고 모듈



# 추가하기
def home(request):
    topics = Topic.objects.all()   #models의 Topic 개체 생성
    return render(request,'home.html',{'topics':topics})
    
    #(home html을 렌더링하고 topics개체를 반환한다)
  




 

 

[5.글 작성페이지 작성]

templates폴더에 new_topic.html 을 만들어줍니다. 이 파일은 게시글을 쓸 때 보일 화면입니다. 이 페이지는 위에서 추가했던 content부분에 들어갈 페이지가 됩니다. 아래와 같이 작성해줍니다.

 

{% extends  'base.html' %}

{% block title %} writting {% endblock %}


{% block content %}
    <form method ="post">
        {% csrf_token %}
       
        <!-- writting title -->
        <div class="form-group">
            <label for="id_subject"> 제목 </label>
            <input type="text" class="form-control" id="id_subject" name="subject">
        </div>

        <div class="form-group">
            <lable for="id_message">내용</lable>
            <textarea class="form-control" id="id_message" name="message" rows="5"></textarea>
        </div>
        <button type="submit" class="btn btn-success">게시</button>


</form>
{% endblock %}

 

코드해석

[5.1.form 태그]

 

<form> 태그에서 method 속성을 정의해야 합니다. 

 

웹브라우저에게 어떤식으로 서버와 상호작용할 것인지를 정해주기 때문입니다.

HTTP method는 여러개가 있지만 여기서 쓰인 GET과 POST만 정리하겠습니다.

(향후 이에 관해서도 공부도 할겸 포스팅 할 예정입니다.)

 

1)GET은 서버로부터 데이터를 가져올 때 사용합니다.

  브라우저에서 링크를 클릭하거나 URL을 입력해 들어가는게 모두 GET요청을 만드는 것입니다.

 

2)POST는 서버에 있는 데이터를 바꿀 때 사용 됩니다.  데이터를 업데이트 할 때 사용됩니다.

 

 

[5.2.csrf token(Cross-Site Request Forgery Token)]

CSRF TOKEN은 장고가  모든 HTTP POST request를 보호 할 때 사용됩니다. 이건 외부 사이트 혹은 어플리케이션에서 보내지는 데이터 유출을 막기 위해 사용됩니다. 그래서 장고에서 form의 post 메서드를 쓰면 csrf태그가 뒤이어 따라오게 됩니다. 

 

[5.3.input]

 <input type="text" class = "form-control" id="id_subject" name = "subject">에서

  name 부분은 서버에  데이터를 넘겨줄 때 데이터 구분용으로 쓰입니다

 

[5.4.textarea]

 <textarea class="form-control" name="message" rows='5'>에 쓰인 name 부분 역시 서버에 데이터를 넘겨줄 때 쓰입니다.

 

 

 

view에서 함수를 작성할 때 

 subject =  request.POST['subject'] 
 message =  request.POST['message']

 

이런 식으로 참조합니다.

 


[6. view  new_topic 함수  추가]



#사용자정의
from django.contrib.auth.models import User




#렌더링
from django.shortcuts import render, redirect


from  .models import Topic, Reply
# 모델의 클래스명

from django.http import HttpResponse





def home(request):
    topics = Topic.objects.all()
    return render(request,'home.html',{'topics':topics})

# 위 내용과 같다.


# 추가하기
def new_topic(request):

    topics = Topic.objects.all()
    if request.method =='POST':
        subject = request.POST['subject']
        message = request.POST['message']

        user = User.objects.first()

        topic = Topic.objects.create(
            subject=subject,
            message=message,
            writter=user
        )

        post = Reply.objects.create(
            message=message,
            created_by=user

        )

        return redirect('home')
  
       
    
    return render(request,'new_topic.html',{'topics':topics})

 

[new_topic 화면]

 

 

 

그런데 게시를 눌러도 아직 아무것도 표시가 안될 것입니다. 왜냐면 home.html에서 new_topic html에서 넘겨받은 객체들을 어떻게 표시할지 작성하지 않았기 떄문입니다.

 

 

 

[6. home.html 내용작성]

조회수와 댓글수는 나중에 구현할 것이라, 현재 html페이지에서는 0으로 고정시켜놓았습니다.

{% extends  'base.html' %}
     {% block content %}
        <table class="table">
            <thead class="bg-info">
                <tr> 
                    <th>작성자</th>
                    <th>제목</th>
                    <th>조회수</th>
                    <th>댓글수</th>
                    <th>작성일자</th>
                </tr>

            </thead>

            <tbody>
                {% for topic in topics %}
                <tr>
                    <td>{{topic.writter.username }}</td>
                    <td>{{topic.subject }}</td>
                    <td>0</td>
                    <td>0</td>
                    <td>{{topic.last_updated}}</td>
                </tr>
                {% endfor %}

            </tbody>
          
        </table>

  {% endblock %}

 

 

[실행화면]

 

 

 

 

 

그런데 우리가 게시글을 쓸때 url로 주소 입력해서 게시글 페이지로 들어가지 않잖아요?

보통 버튼을 눌러서 게시글 작성하니깐 그 버튼을 home.html에 추가해보도록 하겠습니다.

 

 

[글 작성버튼 만들기]

테이블 태그 하단에 div 태그를 추가해줍니다. 버튼을 만들어 아까 만든 new_topic url로 이동시키는 역할을 합니다.

 

{% extends  'base.html' %}
     {% block content %}
        <table class="table">
            <thead class="bg-info">
                <tr> 
                    <th>작성자</th>
                    <th>제목</th>
                    <th>조회수</th>
                    <th>댓글수</th>
                    <th>작성일자</th>
                </tr>

            </thead>

            <tbody>
                {% for topic in topics %}
                <tr>
                    <td>{{topic.writter.username }}</td>
                    <td>{{topic.subject }}</td>
                    <td>0</td>
                    <td>0</td>
                    <td>{{topic.last_updated}}</td>
                </tr>
                {% endfor %}

            </tbody>
          
        </table>
        
        <!-- add creating posting button  게시글 버튼-->
        <div class="mb-4">
            <a href="{% url 'new_topic' %}" class="btn btn-info"><b>글 작성</b></a>
        </div> 


  {% endblock %}

 

 

 

 

 

 

 

[참고 사이트]

https://medium.com/@lyhlg0201/http-method-d561b77df7

 

HTTP Method

음.. 개발자가 되어서 이런걸 정리하게 될줄은 사실 몰랐다.

medium.com

https://getbootstrap.com/docs/4.0/components/buttons/

 

Buttons

Use Bootstrap’s custom button styles for actions in forms, dialogs, and more with support for multiple sizes, states, and more.

getbootstrap.com