본문 바로가기

사이드 프로젝트/django

Django 로 게시판 만들기 3-1.게시판 뼈대 만들기

[개발환경:ubuntu20.04 lts]

배우게 될 것: 장고의 admin, model,views, templates,urls

 

 

[1. 게시판 전체 개요]

 

앞으로 만들 게시판은 큰 게시판에 여러개의 주제가 있고 그 속에서 사용자가 글을 쓸수 있게 하고, 글에 댓글을 달게 하는 구조입니다. 관리자만이 전체 게시판을 생성하고 관리할 수 있습니다. 그리고 게시글 생성이나 댓글을

사용자가 달 수 있는 구조입니다.

 

전체적인 게시판 뼈대를 디자인해보겠습니다.

 

(1)게시판 첫번째 페이지

첫번째 게시판에 접속했을때 상단에 로그인과 로그아웃기능이 있고,프로필을 누르면 정보수정 기능을

배치할것입니다. 그리고 상단의 Django 버튼을 누르면 게시판 홈으로 돌아오게끔 할 것 입니다.

 

그리고 하단에는 게시글을 작성할 수 있게끔 글쓰는 기능을 배치합니다. 그리고  제목 혹은 작성자로 검색하게 하는 검색바를 배치합니다.

 

 

 

(2)게시글 화면

댓글을 달 수 있고 댓글에 댓글은 댓글라인 옆에 있는 댓글달기 버튼을 눌러서 달 수 있게 합니다.

댓글을 달 때는 글 뿐만 아니라 사진첨부 기능도 첨부할 수 있도록 할 것입니다.

게시글 하단 부분에는 해당 게시글의 이전 게시글과 다음 게시글을 목록으로 표시되게 할 것 입니다.

 

(3)게시글 작성 페이지

 

(4)로그인 페이지

(5)비밀번호 재설정 페이지

(6)회원가입 페이지

https://app.diagrams.net/

 

Flowchart Maker & Online Diagram Software

Flowchart Maker and Online Diagram Software diagrams.net (formerly draw.io) is free online diagram software. You can use it as a flowchart maker, network diagram software, to create UML online, as an ER diagram tool, to design database schema, to build BPM

app.diagrams.net

으로 UI디자인을  했습니다.

 

[2.클래스 다이어그램]

 

 

게시판 초안

 


 

이제 해당 게시판으로 왔으면

게시글과 관계를 살펴보아야 합니다.

 

Name은 글 제목

User는 작성자(외래키)

content는 글내용 입니다.

Created at은 최초 작성일자 입니다.

 


게시판 사용자는 여러 토픽에서 글을 쓸 수 있어서 1:n의 관계입니다.

 

Email:이메일양식

admin:관리자인지 확인 아니면 false

 

 

 

 


모든 게시글은 각각 한명의 User에 의해 작성됩니다.

 

 

 

 

 

 

 


[3.모델 만들기]

 

모델은 기본적으로 장고의 어플리케이션의 데이터베이스 레이아웃입니다.

 

이전에  미리 만들어둔 장고 어플리케이션 여기선  board1 이라는 어플리케이션의  models을 클릭합니다.

 

 

 

 

 

여기에 아까 설계한 model들을 작성합니다.(Board,Post,Topic,User)

*User 모델은 이미 장고내에 django.contrib.auth.models 에 정의되어 있습니다. 따로 작성할 필요가 없습니다.

 

실제로 해본 결과 모델 설계를 잘못해서 다시 수정한 파일을 올립니다 죄송합니다(2021년 5월 13일)

 

이대로 수정하시고 python manage.py makemigrations 한 후에 python manage.py migrate를 진행해주시면  변경된 모델이 

장고에 반영됩니다.

 

 

from django.db import models

from django.contrib.auth.models import User

class Topic(models.Model):
    message = models.TextField(max_length=5000,null=True)
    subject = models.CharField(max_length=255)
    last_updated =  models.DateField(auto_now_add=True, null=True)
    writter = models.ForeignKey(User, related_name='topics',on_delete=models.CASCADE, null=True)    

class Reply(models.Model):
    message = models.TextField(max_length=5000)
    created_at = models.DateTimeField(auto_now_add=True)
    created_by= models.ForeignKey(User, null=True, related_name='posts',on_delete=models.CASCADE)
    updated_at = models.DateField(null = True)
    updated_by=  models.ForeignKey(User,null=True,related_name='+',on_delete=models.CASCADE)

 

(코드 수정하시고 진행)

python manage.py makemigrations
python manage.py migrate

 

모든 모델들은 django.db.models.Model 클래스입니다. 이 클래스들이 데이터베이스의 테이블 로 변환됩니다.

 

각각의 필드(여기선 정의한 클래스의 속성들)는 django.db.models.Field 서브클래스로 됩니다.

 

 이 서브 클래스가 데이터베이스의 칼럼으로 변환됩니다. 그리고 이 칼럼은 여러 데이터 타입으로 채워집니다.

(*장고는 넓은 데이터 타입을 제공합니다.)

 

 

 

ex)charField:문자, TextField:문자열,DateTimeField날짜 등등 많은 데이터 타입이 있습니다

 


[3.1 Topic모델(클래스)]

class Topic(models.Model):
    message = models.TextField(max_length=5000,null=True)
    subject = models.CharField(max_length=255)
    last_updated =  models.DateField(auto_now_add=True, null=True)
    writter = models.ForeignKey(User, related_name='topics',on_delete=models.CASCADE, null=True)    

 

Topic모델은 게시판 화면에 어떤 요소들을 보여줄것인지에 대한 것입니다.

 

그래서 클릭하면 들어가서 글내용을 볼수있어야 하니깐 message필드를 만들어줍니다.

subject는 글제목입니다.

 

last_updated는 글 게시한 날짜를 올려줍니다.

writter는 글 작성자를 나타냅니다.


[3.2 Reply모델(클래스)]

class Reply(models.Model):
    message = models.TextField(max_length=5000)
    created_at = models.DateTimeField(auto_now_add=True)
    created_by= models.ForeignKey(User, null=True, related_name='posts',on_delete=models.CASCADE)
    updated_at = models.DateField(null = True)
    updated_by=  models.ForeignKey(User,null=True,related_name='+',on_delete=models.CASCADE)

Reply 모델은 댓글을 위한 모델입니다.

-message는 댓글내용입니다

-created_at은 댓글을 단 시간을 표시합니다.

-updated_by는  댓글 작성자를 표시합니다.

 

ForeignKey필드는 다른 클래스의 주키(속성)가 현재 모델의 속성이 될 때 참고해야되어서 쓰입니다.

 

 

[Foreighnn key의 reverse relationship]

foreignkey를 보면 related_name이라는 파라미터 옵션값이 있습니다. 이것은 다른 클래스의 instance값들을 해당 모델에 접근할수 있게끔 해줍니다. 장고는 reverse relationnship을 자동으로 생성해줘서 이는 선택사항입니다.

 

하지만 자동으로 생성되는 이름이 직관적이지 않아서 이 옵션을 사용했습니다. 예를 들면 USER클래스를 참조한다고 하면 

USER_set 이런식으로 자동 생성됩니다.

 

여기선 USER 클래스에서  posts라는 이름으로  post인스턴스 속성을 이용할수 있게 됩니다.

 

예를 들면 User클래스에서  첫번째 user에게 할당된 모든 post들을 가져오려면

 

User.object.first( ).posts.all()

 

 

그리고 related_name='+'는 해당 필드는 reverse realtionship을 필요로 하지 않는다고 명시하는 것입니다.

 

 

 

 

created_at 필드의  auto_now_add 옵션을 True로 하면  게시하는 시간이 기록되어 기록됩니다.

 

 

 


[4.Migration]

(* 3번에서 이미 마이그레이션을 했다면 건너뛰셔도 무방합니다.)

 

마이그레이션은 장고에게 데이터베이스를 만들것이라고 말하는 것입니다.

그러니깐 장고에서 데이터 베이스를 만들기 위한 과정이라고 보시면 됩니다.

(migrate라는 뜻은 이주하다 라는 뜻인데, 장고로  "데이터베이스를 만들어 간다", "이주한다" 느낌으로 이해하시면 될 것 같습니다) 


cf)

그럼 데이터베이스는 어디 설정되어 있느냐 하면  settings.py파일에 아래와 같이 기본 설정 되어 있습니다.

데이터베이스는 sqlite3로 되어있고, 이는 다른 종류의 데이터베이스로 변경도 가능합니다.


 

터미널을 열고, 프로젝트 상위 폴더로 이동해 다음과 같이 입력합니다.

python manage.py makemigrations

 

여기서 장고가 0001_initial.py라는 파일이 생긴것을 확인할수 있습니다.

이건 현재 우리의 어플리케이션 모델들 상태를 보여주는 것입니다.

 

어플리케이션에 관한 내용은 두번쨰 포스팅을 참고하시면 될 것 같습니다.

 

 

 

장고는 이 0001_initial.py 파일을 참고하여 db의 테이블을 만들고 칼럼을 만듭니다.

 

데이터 베이스로 변환하기 전단계로 보면 될 것 같습니다.

 

 

0001_initial.py파일을 보면 class만든 모델들이 데이베이스 언어인 sql로 바뀌어 있는것을 확인할수 있습니다.

그리고 migrate작업에서 장고는  이 파일을 참조하여 실제 데이터베이스를 만듭니다

 


이제 실제로 데이터 베이스 테이블과 칼럼으로 변환 시키겠습니다.

 

아래와 같이 명령해줍니다.

$ python manage.py migrate

 

migrate 명령어는 장고 어플리케이션의 migration파일(0001_init.py)을 적용시켜 데이터베이스의 테이블과 칼럼을 만듭니다.


[5.게시판 뼈대 만들기]

[5.1 Django Template Engine Setup]

장고 템플릿 언어

장고 템플릿 언어는 장고로 개발할 시 html 템플릿에서 사용할 수 있는 특별한 규칙 또는 문법이고, 
템플릿 변수, 템플릿 필터, 템플릿 변수, 템플릿 코멘트 등이 있습니다.

 

데이터베이스(장고의 models)에 저장된 내용을 html  즉 웹페이지로 보여주게 하기 위해서 템플릿이 필요합니다.

그리고 템플릿을 활용하여 html을 만든 뒤에는 view로 연결 시켜 웹페이지를 연결시킵니다.

 

 

3*템플릿언어를 쓰면 view에서 정의한 함수의 리턴값을 받아서 사용할 수 있습니다.

 

(뷰(view)는 모델과 템플릿을 연결하는 역할을 합니다.)

지금보니 엉터리로 썼군요. template폴더는 앱과 같은 위치레 있어야 합니다.

boardPj/                  .
 |-- makeBoard/             
 |    |-- myproject/
 |    |    |-- __init__.py
 |    |    |-- settings.py
 |    |    |-- urls.py
 |    |    |-- wsgi.py
 |    |-- boards1/                
 |    |    |-- migrations/        
 |    |    |    +-- __init__.py
 |    |    |-- __init__.py
 |    |    |-- admin.py
 |    |    |-- apps.py
 |    |    |-- models.py
 |    |    |-- tests.py
 |    |    +-- views.py
 |    |--templates/ <--template 폴더
 |    +-- manage.py
 +-- boardVenv/                  

[5.2 template 세팅]

템플릿 언어를 쓰기 위해선 설정이 필요합니다.settings.py 파일로 가서 TEMPLATES 영역을 찾습니다.

템플릿 디렉토리를 설정하는 것입니다.

 

 

'DIRS': [
            os.path.join(BASE_DIR, 'templates') #추가해주세요
        ],

 

dirs부분을 아래와 같이 바꿔줍니다. 이건 전체 경로와 templates을 추가하는 부분입니다.

 


1.템플릿 폴더를 아래와 같이 만들어줍니다.

2.템플릿 폴더에 html파일을 만들어줍니다.


3.view파일로 가서 방금 만든 html파일 을 연결시켜줍니다.

 

def home(request):
    return render(request,'home.html')

home함수 안에 request 파라미터는 render함수를 통해 home.html 파일을 반환해줍니다.

 

 

4.url파일로 가서 방금 만든 view파일을 url로 연결시킵니다.

 

url 폴더는 장고 앱(board1)보다 상위 폴더 프로젝트(makeBoard)에 있습니다.

view의 home함수안에 반환받은 home.html을 url로 연결시켜줍니다.

from boards1 import views #1.추가해주기

urlpatterns = [
     path('', views.home,name='home'),#2.view 함수를 url에 연결시키기
     path('admin/', admin.site.urls),
]

 

*주석해석

1.view에 제가 만든 templates/home.html을 받아 오기 위해선 view를 불러와야 합니다. 

 

2.urlpatterns의 path의 첫번째 ' ' 부분은 주소(지금은 127.0.1:8000)에 http://127.0.0에 해당되는 페이지 입니다.

   (그래서 두번쨰 path에 보면 admin/ 이 있는데 이는 127.0.1:8000/admin에 해당되는 페이지입니다)

  

 

그리고 view.home 부분은 view의 home함수를 적용시킨다는 의미입니다.

마지막으로 name='home' 은 view에서 만든 함수 리턴값(home.html)을  웹페이지에 띄어줍니다.

 

 

5.화면

자세한 문법에 관해서는 해당 문서를 보면 됩니다.

https://docs.djangoproject.com/en/3.1/topics/templates/

 

Templates | Django documentation | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

 


[5.3 테이블 만들기]

 

[5.3.1 static파일 설정]

 

기본테이블이 아닌 디자인 된 테이블 을 쓸 건데, 그러기 위해선 static파일들이 필요합니다.

 

static파일은 CSS, JacaScripts,Fonts,Image 등 UI(User Interface)를 구성하는 요소를 의미합니다. 장고는 이런 파일들을 제공하진 않습니다.

 

하지만 Static파일들을 관리하는 걸 도와주는 기능은 있습니다. django.contrib.staticfiles 라는 앱을 통해 관리 기능을

사용할 수 있습니다.

 

그리고 Bootstrap을 통해 이미 디자인된 UI요소들을 쓸 수 있습니다.

 

이제 bootstrap을 쓰기 위해 static폴더와 그 안에 css폴더를 만들어보겠습니다.

boardPj/                  .
 |-- makeBoard/             
 |    |-- myproject #프로젝트명
 |    |-- boards1/ #앱           
 |    |--templates/ #템플릿폴더
 |    |--static/css #static 폴더    
 |    |- manage.py
 +-- boardVenv/                            

 

 

 

이렇게 static 폴더안에 css 폴더를 만들어줍니다.

 

 

 

 

이제 https://getbootstrap.com/docs/4.5/getting-started/download/ 으로 접속해서 compiled css and js라고 적힌 탭을 눌러

다운로드합니다.(2020.12월3일기준  4.5.3버젼이네요)

 

 

 

다운을 받으면  아래와 같은 파일이 있고 그 파일 안에 css라는 파일이 있습니다.

 

 

그 css파일안에 bootstrap.min.css라는 파일을 아까 만들었던 static/css 폴더에 복사합니다.

 

settings.py에서 static파일 설정하기

 

처음에 settings.py에 들어가면 static 설정부분이 이런식으로 되어있습니다.

 

이 부분을  아래와 같이 바꿔줍니다.

(게시글 관리를 안해서 다시 시작하니, djano 3.0.8에서는 STATICFILE_DIRS라고 명시해야 static 디렉토리를 

인식하는듯 했습니다. 22.2.2(수)기준)

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static')
]

이제 bootstrap의 css파일을  home.html에 load해줍니다.

 

    {% load static %} <!--static파일을 로드합니다-->
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='utf-8'>
      
        <title>Page Title</title>
        <link rel = "stylesheet" href="{% static 'css/bootstrap.min.css'%}">
        <!--static파일의 부트스트랩 css 주소를 알려줍니다-->
     

    </head>
   
    
    <body>
      
    </body>

    </html>

 

5*     {% static %} 템플릿 태그는 정적 파일의 절대 URL을 생성합니다.

주석해석

 

  {% load static %}

  static 파일들을 처리할수 있도록 load해줍니다.

 

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

부트스트랩의 css자료들을 쓸 수 있게 css파일이 저장된 위치를 알려줍니다.

 

그리고 여기서 {% static %} 장고 템플릿 태그는 setting.py에서 지정해줬던 STATIC_URL부분을 참고하게하는 태그입니다.


이제 간단히 부트스트랩으로 디자인 효과를 주면 어떻게 될지 간단히 살펴보겠습니다.

    {% load static %} 
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='utf-8'>
      
        <title>SEONGHYUK BOARD</title>
        <link rel = "stylesheet" href="{% static 'css/bootstrap.min.css'%}">
     

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

    </body>

    </html>

여기서 nav class와 div class에서 쓰인것들이 모두 부트스트랩 디자인중 특정 부분을 쓴다는 뜻입니다.

저는 상단을 파란색 배경으로 네비게이션바를 한번 만들어보겠습니다. 

 


이곳을 참고하면 navbar에 대해서 더 자세히 알수 있습니다.

 

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

 

Navbar

Documentation and examples for Bootstrap’s powerful, responsive navigation header, the navbar. Includes support for branding, navigation, and more, including support for our collapse plugin.

getbootstrap.com

이곳을 참고하면 navbar에 대해서 더 자세히 알수 있습니다.

 


 

[5.4 base.html 만들기]

계속 고정되는 메뉴바

우리는 상단에 메뉴바는 고정 시킨채로 게시판을 만들것이기 때문에 새로운 웹페이지를 만들때마다 상단 메뉴 html을 작성하는 것을 비효율적입니다, 그래서 base.html이라는 것을 만들어 확장되는 방식으로 작성해야 합니다.

 

 

 

 

templates/base.html

다음과 같이 작성합니다.

{% load static %}
<!DOCTYPE html>
<html>
<head>
    <meta charset = "utf-8">
    <title>SEONGHYUK BOARD</title>
    <link rel = "stylesheet" href="{% static 'css/bootstrap.min.css'%}">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
            
            <div class="container">
                <a class="navbar-brand" href="{% url 'home' %}"><b>BOARD</b> </a>
            </div>
     </nav>

     <br>
     <br>   
     <div class="container">
       
        {% block boardhead %}
        {% endblock %}

     </div>

    
</body>
</html>

주석 설명

 

1){% block boardhead %}는 이 자리에 이제 boardhead라는 이름을 가진 태그의 내용을 넣는다는 의미입니다.

여기는 계속 쓸 html파일을 만드는 파일이라 구체적인 내용은 각각 html로 만들어 줄 거라 공간을 미리 부여해준다고 생각하면 됩니다. (뒤에 나올 home.html에  boardhead라고 적은 부분을 이어받아  구체적으로 작성할 것입니다.)

 

block뒤에 이름은 원하시는 이름을 해도 됩니다(저는 여기서 boardhead 라고 했습니다)

 

그리고 block태그를 썼으면 {% endblock %}태그를 써야 block태그가 들어갈 공간을 만듭니다.

 

 

 

 

[5.5 home.html 수정하기]

그럼 이제 저 block태그에 들어갈 내용을 template/home.html에 작성해봅니다.

 

 이전에 작성되었던 template/home.html에는아래와 같이 작성해줍니다.

{% extends 'base.html' %}

{% block boardhead %}
    <table class="table">
        <thead  class="thead-inverse">
            <tr>
                <th>index</th>
                <th>제목</th>
                <th>조회수</th>
                <th>작성자</th>
                <th>댓글수</th>
                <th>작성일자</th>
            </tr>
        </thead>
    </table>

{% endblock %}

 

주석 설명

{% extends base.html %}은 위에 작성한 base.html의 내용을 이어받는다는 선언입니다.

 

{% block boardhead %} {% endblock %}부분은  base.html에 들어갈 부분을 상세하게 적을 수 있도록 준비 해줍니다.

내용이 들어갈 공간을 미리 선언한다고 보시면 됩니다.

 

 

<thaed class ="thead-inverse"> 테이블의 디자인에 대해 부트스트랩에 만든 클래스입니다.

자세한 건 아래 링크를 참조하시면 되겠습니다. 아래표는 예시입니다.

https://getbootstrap.com/docs/4.0/content/tables/


그냥 thead 일 경우

<thead class="thead-light"> 일경우

 

포스팅이 너무 길어질 것 같아 여기서 우선 마무리하고 다음 포스팅은 게시글을 올리는 내용으로 포스팅하겠습니다.


[참고 사이트]

https://simpleisbetterthancomplex.com/series/beginners-guide/1.11/

 

A Complete Beginner's Guide to Django

A Django tutorial series for complete beginners. A comprehensive guide covering all the basic aspects of Django models, views, templates, testing, admin.

simpleisbetterthancomplex.com

https://opentutorials.org/module/4034/24660

 

templates 구성 - Django

templates 구성 2019-04-17 20:47:31 templates 구성 우리는 홈 화면을 구성하기 위해 html 문서를 만들어야 합니다. 이러한 html 문서를 관리하기 위한 것이 [templates]입니다.   우리는 [blogapp] 안에서 홈 화면

opentutorials.org

http://pythonstudy.xyz/python/article/312-Django-%ED%85%9C%ED%94%8C%EB%A6%BF-%ED%99%95%EC%9E%A5

 

예제로 배우는 파이썬 프로그래밍 - Django 템플릿 확장

1. 템플릿 확장 웹사이트를 개발하다 보면 모든 (혹은 많은) 웹 페이지마다 공통적으로 들어가는 HTML 코드가 있음을 알게 된다. 각 웹페이지마다 공통 코드를 중복해서 넣어 주는 것은 효율적이

pythonstudy.xyz

 

https://velog.io/@hidaehyunlee/Django-%ED%85%9C%ED%94%8C%EB%A6%BF-%EC%96%B8%EC%96%B4

 

 

[Django] 템플릿 언어

템플릿 언어를 사용하면 HTML 작업을 훨씬 수월하게 할 수 있다.

velog.io

https://docs.djangoproject.com/ko/3.0/intro/tutorial06/

 

첫 번째 장고 앱 작성하기, part 6 | Django 문서 | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

https://nachwon.github.io/django-deploy-4-static/

 

[Deploy] Django 프로젝트 배포하기 - 4. Static 파일

이번 포스트에서는 static 파일들을 서버에 업로드하여 적용시키는 방법에 대해 알아본다.

nachwon.github.io

nachwon.github.io/django-8-template/

 

[Django Tutorial] Blog 만들기 - 8. 템플릿

이제 우리는 원하는 내용을 원하는 주소에 표시하는 방법을 알았다.그럼 이제 원하는 내용을 그럴싸하게 꾸며서 보여주기만 하면 된다.이제 우리의 블로그가 사용자에게 어떻게 보여질지를 한

nachwon.github.io

blog.naver.com/PostView.nhn?blogId=nackji80&logNo=221396512736&parentCategoryNo=&categoryNo=53&viewDate=&isShowPopularPosts=false&from=postView

 

[파이썬 장고 Django] 템플릿(templates) 폴더 위치 설정하는 방법

네트워크 프로그래머, 청년 고득녕입니다. 장고(django)에서 templates를 생성할때, 특정 폴더에 templates...

blog.naver.com

leemoney93.tistory.com/24

 

Django related_name(reverse 역참조 )

Django ORM related_name, 역참조 삽질기 남긴다.. (피가 거꾸로 솟을뻔 했다) 아래와 같은 Model이 있다고 하자 차량(Car)이 있고 해당 차량에 적재할 수 있는 팔레트(Pallet)가 있다고 하자. class Car(models.M..

leemoney93.tistory.com