[REAL Python – Flask] – “인스타그램 클론코딩 – Instagram Clone (1)”

[REAL Python – Flask] – “인스타그램 클론코딩 – Instagram Clone (1)”

2022/08/29 4:15 PM

프로젝트 세팅

먼저, 저는 플라스크 프로젝트들을 flaskprojects 라는 디렉토리에 넣어서 관리하고 있습니다.

입력하여 flastagram 폴더를 하나 만들어 주겠습니다.

이후, cd flastagram 으로 해당 폴더로 이동한 다음 mkdir backend, mkdir frontend 로 각각 디렉토리를 만들어 주세요.

frontend 폴더 안에는 위와 같은 디렉토리 구조를 만들어 주세요. index.html 파일의 내용은 아무것도 없습니다.

터미널을 통해 backend 폴더로 이동한 다음, python -m venv venv 를 입력하여 가상환경을 설치해 줍니다.

가상환경을 활성화해 줍니다. 필자는 WSL 우분투를 이용하고 있어서 위의 명령어를 사용했는데, Windows의 경우는 venv/scripts/activate 를 입력하면 될 겁니다.

mkdir config
mkdir models
mkdir requirements
mkdir resources
mkdir schemas

터미널에 위의 줄들을 한 줄씩 입력하여 아래와 같은 디렉토리 구조를 만듭니다. 터미널의 현재 위치가 flastagram/backend 에 있는 것을 꼭 확인해 주세요. (오타 수정 : shcemes -> schemas)

다음으로는 우리가 필요한 라이브러리들을 설치하겠습니다.

pip install flask

pip install flask-jwt-extended

pip install python-dotenv

pip install flask-restful

pip install flask-migrate

pip install flask-uploads

pip install flask-marshmallow

pip install marshmallow-sqlalchemy

pip freeze 를 입력하면 아래와 같이 설치된 패키지들의 목록이 뜰 겁니다.

pip freeze > requirements/common.txt 로 해당 패키지들의 버전을 명시해 두겠습니다. 주의할 점은, backend/ 폴더 안에서 명령어를 수행해야 한다는 것입니다. 아래 스크린샷의 하늘색 부분의 오른쪽 맨 끝을 보면 이해할 수 있습니다.

backend / requirements 폴더의 common.txt 파일로 가 보면 아래와 같이 패키지 버전들이 잘 명시된 것을 확인할 수 있습니다.

이후 requirements/ 아래에 dev.txt 파일을 하나 만들어 주고 내용은 -r common.txt 로 채워 줍니다. (common.txt 의 패키지들을 모두 설치하겠다는 이야기입니다)

또, requirements/ 아래에 prod.txt 파일을 하나 만들어 주고, 내용은 같이 -r common.txt 로 채워 줍니다.

pip install -r backend/requirements/dev.txt 를 입력해 보세요. 아래와 같이 “모든 패키지는 다 설치되었어!” 라고 알려주면 성공입니다.

위와 같이 requirements 를 분리하는 이유는, 개발 시에 필요한 패키지들과 배포 시에 필요한 패키지들을 분리하기 위합입니다.

이후 backend/ 아래에 .env 파일, .env.example 파일을 하나 만들어 줍니다.

.env.example 파일에는 아래의 내용을,

JWT_SECRET_KEY = 
APP_SECRET_KEY = 
APPLICATION_SETTINGS = config/dev.py
DATABASE_URL =

.env 파일에는 아래의 내용을 넣어 줍니다. (SECRET_KEY 에는 어떤 것을 넣던 관계없습니다.)

JWT_SECRET_KEY = flastagramsecretkey
APP_SECRET_KEY = flaskappsecretkey
APPLICATION_SETTINGS = ../config/dev.py

다음 config 파일을 만질 차례입니다. config 파일 또한 개발용, 배포용을 따로 만들어 분리해 두겠습니다.

config 폴더 아래에 비어있는 __init__.py 를 만들어 주세요.

그리고 아래와 같은 이름을 가진 파일들을 만들어 줍니다.

backend/config/common.py 에 아래의 내용을 넣어줍니다. 맨 아래의 print 를 수행한다면 끝이 /backend 가 되어야 합니다.

import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# print(BASE_DIR)

backend/config/dev.py 에는 아래의 내용을,

from config.common import *
import os

DEBUG = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(os.path.join(BASE_DIR, 'flastagram.db'))
SQLALCHEMY_TRACK_MODIFICATIONS = False
PROPGATE_EXECPTIONS = True
JWT_SECRET_KEY = os.environ["JWT_SECRET_KEY"]
SECRET_KEY = os.environ["APP_SECRET_KEY"]
JWT_BLACKLIST_ENABLED = True
JWT_BLACKLIST_TOKEN_CHECKS = ["access", "refresh"]

prod.py 에는 아래의 내용을 넣어줍니다. 아직 배포용 설정은 하지 않도록 하겠습니다!

from .common import *

그 다음으로는, backend 아래에 api 폴더와 __init__.py 를 하나 만들어 주겠습니다.

그리고 이 세 개의 디렉토리들을…

api 폴더 아래로 옮겨줍니다.

현재의 디렉토리 구조는 아래와 같습니다.

flastagram
├── backend
│   ├── api
│   │   ├── __init__.py
│   │   ├── models
│   │   ├── resources
│   │   └── schemes
│   ├── config
│   │   ├── __init__.py
│   │   ├── common.py
│   │   ├── dev.py
│   │   └── prod.py
│   ├── requirements (설치된 패키지들)
│   │   ├── common.txt
│   │   ├── dev.txt
│   │   └── prod.txt
│   └── venv (파이썬 가상환경)
└── frontend
    ├── assets
    │   ├── css
    │   ├── img
    │   └── js
    └── index.html

그리고 __init__.py 에 create_app() 함수를 작성해 주겠습니다.

그리고, backend 폴더 아래에 app.py 를 만들어 줍니다.

이후 터미널의 위치가 flastagram/backend 인 것을 확인한 후, 아래의 명령어를 입력해 보세요.

서버가 위와 같이 열린다면 성공입니다!

백엔드 단에서 간단한 준비

backend/api 아래에 db.py 를 작성하고, 아래의 내용을 입력해 주겠습니다.

이번에는 flask-marshmallow 를 사용하기 위해서, backend/api 아래에 ma.py 를 작성하고, 아래의 내용을 입력합니다.

models.py 아래에 비어있는 __init__.py 파일을 작성해 줍니다.

그리고 각각 user.py, post.py, comment.py 를 작성해 주세요. 먼저 User 모델을 구현하겠습니다.

이후, api/__init__.py 에 아래의 내용을 추가합니다.

# 아래의 줄에 jsonify 추가!
from flask import Flask, jsonify
from flask_restful import Api
from dotenv import load_dotenv

# 추가!
from flask_jwt_extended import JWTManager
from flask_migrate import Migrate
from marshmallow import ValidationError

# 추가!
from .db import db
from .ma import ma
from .models import user

def create_app():
    app = Flask(__name__)
    load_dotenv(".env", verbose=True)
    app.config.from_object("config.dev")
    app.config.from_envvar("APPLICATION_SETTINGS")
    api = Api(app)
    
    # 추가!
    jwt = JWTManager(app)
    migrate = Migrate(app, db)

    db.init_app(app)
    ma.init_app(app)
    migrate.init_app(app, db)
    
    # 추가!
    @app.before_first_request
    def create_tables():
        db.create_all()
        
    # 추가!
    @app.errorhandler(ValidationError)
    def handle_marshmallow_validation(err):
        return jsonify(err.messages), 400

    
    return app

이 작업 후, flask db init 을 입력해줍니다. 터미널의 현재 폴더 위치가 backend/ 에 있는 것을 꼭 확인하세요!

이후 backend/ 에 migrations 라는 폴더가 생성된 것을 확인할 수 있을 겁니다.

다음으로는, flask db migrate 명령을 입력해줍니다.

위와 같이 User 테이블을 찾아냈고, 리비전 파일을 만들어냈다.

그러면 migrations 아래에 40… 라는 리비전 파일이 들어가있는 것을 확인할 수 있을 겁니다.

잠시 생성된 파일을 살펴보겠습니다. 우리가 만들어낸 User 모델을 인식하고, 어떤 필드를 만들지, 제약 조건은 어떻게 할 지에 대해서 적혀 있는 것을 볼 수가 있네요. upgrade 라는 함수를 수행하면 create_table 이 되고, downgrade 라는 함수를 수행하면 User 테이블을 drop 합니다.

flask db upgrade 명령을 수행해 보세요. 아래와 같이 데이터베이스에 테이블이 잘 추가되었을 겁니다.

팔로우 / 언팔로우를 위한 유저 모델 구현

우리는 팔로우/언팔로우를 구현할 것이므로, 모델을 수정해야 합니다. 한 명의 유저는 여러 명의 유저를 팔로우할 수 있고, 또 다른 유저도 다른 여러 명의 유저를 팔로우할 수 있습니다. 이는 다대다 관계입니다.

“게시물과 태그” 는 제가 제일 좋아하는 다대다 관계로서의 예시입니다. 그런데, “게시물 테이블” 과 “태그 테이블” 은 따로 존재합니다. 팔로우와 언팔로우의 경우에는 유저가 유저를 팔로우합니다. 유저 테이블 딱 하나만 존재합니다. 이를 구현하기 위해서 이 둘을 매핑해 주는 연관 테이블을 작성하겠습니다.

이후 유저 테이블에서 팔로우 관계를 설정합니다. 주석은 달아 놓았는데, 더 정확한 설명은 아래의 링크를 참고하면 좋을 듯 싶습니다.

https://stackoverflow.com/questions/19598578/how-do-primaryjoin-and-secondaryjoin-work-for-many-to-many-relationship-in-s

이후, 아래의 함수를 작성합니다.

follow() 메서드는 호출되었을 때에 만약 본인이 누군가를 팔로우하지 않고 있다면 팔로우를 수행할 것이고,

unfollow() 메서드는 호출되었을 때에 만약 본인이 누군가를 팔로우하고 있다면 그 사람을 언팔로우할 것입니다.

이를 위해서 누군가를 팔로우하는 중인지, 아닌지를 판단하는 is_following() 메서드를 추가합니다.

flask db migrate 를 수행하고,

flask db upgrade 를 수행하세요.

그러면, 새롭게 followers 테이블이 생성된 것을 확인할 수 있습니다.

본격적인 구현은 다음 포스팅부터 시작됩니다.

프론트엔드 단에서 간단한 준비

그냥 아래 것 다운로드 받아서 넣어 두세요..

사진은 알아서 구하는 걸로..

이렇게 압축을 풀어서 같은 레벨에 놓아두면 됩니다.

https://drive.google.com/drive/folders/1YUMEyvK0AHDl937Ofgc4lKaiJS1XlpnB 에서 이미지들을 다운받고, 연결해 주세요! (어차피, 나중에 바뀔 것이므로 취향껏..

index.html 을 열었을 때에, 큰 문제 없이 뜬다면 완성입니다~

Leave A Comment

Thank you for visiting!

Thank you for visiting!

If you found this post helpful, please consider sharing and liking it. If you have any questions, feel free to leave a comment. 😎

If you’d like to contact me personally, please use the button below to send me an inquiry email. 📧