어제는 Django, 장고에 대해 간단하게 알아보는 시간을 가졌다.
오늘은 장고에 대해 알아보면서 Pycharm을 이용해 장고 프로젝트를 만들고 직접 코드를 입력해 연습하는 시간을 가져보았다.
우선 Django 프로젝트의 구조로는 User / URL / View / Model / DB 총 5가지의 구조로 이루어져 있다.

여기서 우리가 직접 코딩을 진행할 부분으로는 URL과 View 부분이 있다.
URL은 사용자가 어떤 주소로 접근할 수 있게 정해주는 공간이고, View는 URL에서 특정 역할 및 기능을 수행할 것인지 만들어주는 공간이라고 생각하면 된다.
그렇게 URL은 대부분 urls.py라는 파이썬 파일에서 코드를 구현하고, View는 views.py라는 파이썬 파일에서 코드를 구현해주면 된다.
다음으로 장고를 연습해보기 위해 만든 장고 프로젝트는 SNS 프로젝트이기에 SNS에 필요한 요소를 크게 3가지로 잡고 유저, 포스팅 글, 팔로우로 나눠주었다.
처음으로 유저와 포스팅 글에 대한 것을 만들어 볼 것인데, 해당 프로젝트에서 기능들을 수행해줄 수 있도록 앱(app)을 만들고자 하였다.
다음과 같은 코드를 터미널(Terminal) 창에서 입력을 해주었다.
$ django-admin startapp user
$ django-admin startapp tweet
해당 명령어들을 터미널에 입력해주고 나면 좌측 프로젝트 목록에 user와 tweet의 app 폴더가 생성된 것을 볼 수 있었다.

그리고 생성된 앱들이 장고에서 인식할 수 있도록 해당 프로젝트를 관리하는 모든 정보들이 있는 myDjangoSns의 settings.py 안에 있는 INSTALLED_APPS에 내가 만든 앱들을 추가해주었다.
settings.py는 장고 프로젝트가 어떤 기능 및 설정이 되어있는지 알려주는 곳이라고 생각하면 된다.

해당 INSTALLED_APPS 안에 직접 만든 앱들을 넣어줘야 장고가 해당 앱들이 추가됐음을 인식한다.
이 외 미리 적혀있는 것들은 장고 프로젝트에서 기본적으로 제공해주는 앱이다.
settings.py가 조금이라도 이상하면 해당 장고 프로젝트는 실행되지 않으므로 주의해주어야 한다.
다음은 데이터베이스에 연결하기 위한 설정을 해보자.
장고 프로젝트가 생성되면 좌측의 프로젝트 목록에 db.sqlite3 파일이 존재한다.
해당 파일이 존재하면 데이터베이스에 연결이 잘 되어있다는 의미이다.
이제 해당 파일을 가지고 데이터베이스에 연결해주는 작업을 진행해보자.

우측에 있는 바를 보면 데이터베이스라고 적혀있는 버튼이 있다.
해당 버튼을 누르면 데이터베이스 목록이 열리고, + 표시를 눌러서 경로 데이터 소스를 열어준다.

경로 데이터 소스를 누르면 어느 경로에 무슨 파일을 선택할 것인지 창으로 나타내 주는데, db.sqlite3을 연결해주기 위해 해당 파일을 고른 뒤 확인을 눌러주었다.

확인을 눌러주면 해당 창이 뜨는데 드라이버에서 SQLite를 선택해주고 확인을 누르면 다음과 같은 창이 뜬다.

보통 알아서 설정이 되어있고, 이름을 바꿔주고 싶다면 바꿔도 상관없다.
여기서 중요한 것은 첫 연결 시 주황색 네모 안에 Download missing driver files라는 문구가 있을 것이다.
(해당 사진에서는 이미 누른 뒤라 안 보이는 것)
첫 연결이기에 아무런 설정이 되어있지 않아서 드라이버가 존재하지 않으므로 Download를 눌러 드라이버를 다운로드해주면 된다.
드라이버 다운로드가 끝나면 밑에 있는 연결 테스트(Test Connection)를 눌러서 연결이 잘 되어있는지 확인하고, Succeeded 메시지가 뜨면 적용을 한 뒤 확인을 눌러주면 된다.
다음으로 User Model을 만들어보도록 하자.
우선 유저를 구분하기 위해 어떤 정보를 넣을 것인지 생각해보았다.
해당 프로젝트에서는 사용자 이름, 비밀번호, 상태 정보, 생성일, 수정일을 넣어주도록 했다.

해당 문구들이 무엇인지에 대해서는 다음과 같다.
class UserModel(models.Model): : 유저 모델 클래스 생성
class Meta : 데이터베이스에 정보를 넣어주는 역할
db_table = "my_user" : 데이터베이스 테이블 안에 들어가는 이름 설정
username : 사용자 이름
password : 비밀번호
bio : 상태 정보
created_at : 생성일
updated_at : 수정일
해당 모델 정보들을 적으면서 CharField와 DateTimeField와 같은 필드들을 볼 수가 있는데, 해당 필드들은 장고 모델 필드들의 종류 중 하나로서 필드 종류들에 대해서는 다음과 같다.
문자열 : CharField, TextField
날짜/시간 : DateTimeField, DateField, TimeField
숫자 : IntegerField, FloatField
다른 테이블과 연관 지을 때 : ForeignKey
해당 모델 정보들을 입력해준 뒤 만들어진 데이터베이스 정보들을 장고에 알려주기 위해 다음과 같은 명령어를 터미널에 적어주도록 하자.

python manage.py makemigrations 명령어를 통해 해당 데이터베이스 변경이 이뤄졌다는 것을 알려주고, 이후 변경된 값들을 반영해주기 위해 python manage.py migrate 명령어를 적어준다.

이때, 이미 장고가 만들어놓은 데이터베이스들의 정보도 함께 출력이 된다.
여기서 맨 마지막 줄에 있는 정보가 우리가 만든 모델이기 때문에 해당 모델의 데이터베이스 정보가 잘 적용됐는지 확인해주면 된다.

성공적으로 반영됐다면 데이터베이스 목록에 잘 들어가 있는 것을 확인할 수 있다.
다음으로는 장고의 대표 기능 중 하나인 Admin 기능에 대해 알아보자.
장고는 우리가 직접 코드를 많이 작성하지 않고도 많은 기능들을 사용할 수 있도록 구축되어 있는데, 대표적인 예가 Admin이다.
우선 admin 페이지에서 접속을 하기 위해 관리자(Admin)를 만들어줘야 한다.
터미널 창을 열어 다음과 같은 명령어를 적어주도록 하자.
$ python manage.py createsuperuser

해당 명령어를 입력해주면 관리자의 유저 이름과 이메일, 패스워드를 생성해주는 입력이 뜨게 된다.
맞는 값을 입력한 뒤 엔터를 누르면 successfully라는 메시지와 함께 성공적으로 관리자 계정이 생성된다.
이후 다음 링크로 들어가서 관리자 페이지에 접속하여 확인을 해볼 수 있다.
http://127.0.0.1:8000/admin

직접 입력하여 생성한 관리자의 유저 이름과 패스워드를 입력하고 로그인을 하면 다음과 같은 상세 페이지로 들어갈 수 있다.

아직은 아무런 값도 존재하지 않기에 비어있는 것을 볼 수 있다.
Users를 눌러서 다음 페이지로 넘어가게 되면 생성된 관리자의 정보를 볼 수 있다.

다음으로는 Admin에 모델을 추가해보도록 하자.
장고 프로젝트에서 우리가 만든 앱 폴더인 user의 admin.py 안에 다음과 같은 코드를 적어서 user 앱의 모델을 추가해보도록 하자.
from django.contrib import admin
from .models import UserModel
# Register your models here.
admin.site.register(UserModel) # 만든 UserModel을 Admin에 추가한다.

해당 코드를 입력하고 저장한 뒤 새로고침을 하면 관리자 페이지에서 해당 user 앱의 모델이 추가된 것을 볼 수 있다.

위와 같은 방법으로 글쓰기를 위한 tweet 모델도 추가해주도록 하자.

여기서 from user.models import UserModel은 user 앱에 있는 UserModel 모델을 가져온다는 의미이고, author ~ ForeignKey는 외부 모델을 가져와서 사용하겠다는 의미이다.



이제 회원가입 페이지와 로그인 페이지의 Template을 만들어보도록 하자.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %} | spartaSNS</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
crossorigin="anonymous"></script>
<style>
.title-center {
text-align: center;
margin-top: 50px;
}
.wrap {
width: 400px;
margin: 0 auto;
}
.form-area {
margin-top: 25px;
}
.timeline-container {
margin-top: 25px
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="/">SpartaSNS</a>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#"> 친구 <span class="sr-only"></span></a>
</li>
</ul>
</div>
<form class="form-inline my-2 my-lg-0">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/sign-in"> Sign In <span class="sr-only"></span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/sign-up"> Sign Up <span class="sr-only"></span></a>
</li>
</ul>
</form>
</div>
</nav>
{% block content %}
{% endblock %}
</body>
</html>
위 코드는 회원가입 페이지와 로그인 페이지에서 기본적으로 쓰일 base가 되는 html 코드이다.
이후 회원가입 및 로그인 페이지를 위해 templates 폴더 안에 user 폴더를 만들어주고 signup.html과 signin.html을 작성해주도록 했다.
{# 회원가입 HTML 코드 #}
{% extends 'base.html' %}
{% block title %}
회원가입
{% endblock %}
{% block content %}
<div class="container">
<div class="wrap">
<h2 class="title-center"> 회원가입 </h2>
<form class="form-area" method="post" action="/sign-up/">
{% csrf_token %}
<div class="form-group mt-2 mb-2">
<label for="username">이름</label>
<input type="text" class="form-control" id="username" name="username">
</div>
<div class="form-group mt-2 mb-2">
<label for="password">비밀번호</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<div class="form-group mt-2 mb-2">
<label for="password2">비밀번호 확인</label>
<input type="password" class="form-control" id="password2" name="password2">
</div>
<div class="form-group mt-2 mb-2">
<label for="bio">내 상태정보</label>
<input type="text" class="form-control" id="bio" name="bio">
</div>
<hr>
<div style="float: right">
<button type="submit" class="btn btn-primary">회원가입</button>
<a href="/sign-in" class="btn btn-secondary">로그인 페이지로</a>
</div>
</form>
</div>
</div>
{% endblock %}
{# 로그인 HTML 코드 #}
{% extends 'base.html' %}
{% block title %}
로그인
{% endblock %}
{% block content %}
<div class="container">
<div class="wrap">
<h2 class="title-center"> 로그인</h2>
<form class="form-area" method="post" action="/sign-in/">
{% csrf_token %}
<div class="form-group mt-2 mb-2">
<label for="username">이름</label>
<input type="text" class="form-control" id="username" name="username">
</div>
<div class="form-group mt-2 mb-2">
<label for="password">비밀번호</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<hr>
<div style="float: right">
<button type="submit" class="btn btn-primary">로그인</button>
<a href="/sign-up" class="btn btn-secondary">회원가입 페이지로</a>
</div>
</form>
</div>
</div>
{% endblock %}
{% extends 'base.html %}은 base.html 파일에 해당 코드들을 추가한다는 의미이다.
하나의 html 파일에 코드가 길어지는 것을 방지하여 코드 구현에 있어 편리해질 수 있는 장점이 있다.
그리고 {% csrf_token %}에 대해 잠깐만 알아보자면, CSRF는 Cross Site Request Forgery라는 웹 사이트 취약점 공격 중 하나로 사용자가 본인 의도와는 다르게 공격자가 의도한대로 등록, 수정, 삭제 등을 계속 요청하는 것이다.
장고에서는 해당 공격을 방지하기 위해 csrf_token이라는 토큰을 이용한다.
이제 html 파일이 준비되었으므로 사용자 요청에 따른 url을 가져오기 위한 설정을 해보겠다.
그전에 잠깐 URL - View - Template 동작에 대해 알아보자.

그림을 보며 설명을 해보자면, 사용자가 인터넷 브라우저를 이용해 해당 URL에 접근하게 되면 myDjangoSns에 요청이 접수된다.
해당 요청이 접수된 뒤 myDjangoSns의 urls.py에서 해당 요청이 들어온 URL을 찾은 뒤, 그 URL이 등록된 View를 찾아주는 형식으로 진행된다.
다음으로는 코드를 한번 적어보자.
우선 urls.py에 연결을 해주기 위해 myDjangoSns에 있는 urls.py 안에 해당 코드를 입력해준다.
from django.contrib import admin
from django.urls import path, include
# views.py 파일 불러오기
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('user.urls')),
]
이후 해당 url에 맞는 화면을 보여주기 위한 user 앱의 views.py에 다음과 같은 코드를 추가해준다.
from django.shortcuts import render
# Create your views here.
def sign_up_view(request):
return render(request, 'user/signup.html')
def sign_in_view(request):
return render(request, 'user/signin.html')
마지막으로 작성한 views.py를 urls.py에 연결해주기 위한 다음 코드들을 적어주면 연결이 끝나게 된다.
from django.urls import path
from . import views
urlpatterns = [
path('sign-up/', views.sign_up_view, name='sign-up'),
path('sign-in/', views.sign_in_view, name='sign-in'),
]
이로써 회원가입 페이지와 로그인 페이지가 정상적으로 연결되게 되었다.
해당 페이지의 확인을 위해 다음 링크로 들어가서 확인해보았다.
회원가입 페이지 : http://127.0.0.1:8000/sign-up
로그인 페이지 : http://127.0.0.1:8000/sign-in


-
오늘은 우선 장고에 대한 기본적인 설정들과 회원가입 및 로그인 페이지를 구현해보았다.
확실히 장고를 사용하여 코드를 구현하니 많은 기능들을 제공받아 편리한 것 같다는 느낌을 받았다.
하지만 아직 접한 지 얼마 되지 않은 시점이라 그런지 여러 파일을 왔다 갔다 하며 연결하는 과정에서는 다소 어려움을 겪었다.
이러한 문제는 앞으로 장고 연습 프로젝트를 계속 진행하다 보면 조금이나마 익숙해지는 시간이 되지 않을까 싶다.
한줄평을 하자면 아직 장고에 대해서 접한 시간이 짧고 처음이기에 다소 어렵다는 느낌을 받았다.
:T
'TIL 및 WIL > TIL (Today I Learned)' 카테고리의 다른 글
| [TIL] 2022.05.31 (Django 기초3) (0) | 2022.05.31 |
|---|---|
| [TIL] 2022.05.30 (Django 기초2) (0) | 2022.05.30 |
| [TIL] 2022.05.26 (Django 기초0, Python 문법 복습) (1) | 2022.05.26 |
| [TIL] 2022.05.25 (사물인식 머신러닝 - 팀 프로젝트(끝)) (1) | 2022.05.25 |
| [TIL] 2022.05.24 (사물인식 머신러닝 - 팀 프로젝트3) (0) | 2022.05.25 |