Django - Pystargram

김기훈·2025년 12월 1일

Django

목록 보기
10/17

Day 8 😄


[인스타그램] 회원가입 / 로그인 / 로그아웃

기본세팅 및 가상환경 / 커스텀 유저 / 이메일인증 기능


기본 설정

DB 구조 및 기능


기본 세팅 및 가상환경

  • Pyenv 가상 환경

    • pyenv virtualenv 3.12.1 oz_pystagram → 가상환경 생성

      • pyenv local oz_pystagram → 가상환경 실행

  • Poetry

    • poetry init → Poetry 초기화
      • poetry add django → django 설치
    • django-admin startproject config . → 기초 설정 파일을 생성

  • Python Interpreter와 Language & Frameworks

    • Django 을 설정하여 프로젝트 세팅을 완료


기능 구현

커스텀 유저 만들기

  • python manage.py startapp member

  • models.py 에서 AbstracBaseUser 를 상속받아 User를 커스텀

  • AbstractBaseUser

    • Django의 추상 기반 클래스 중 하나로, 비밀번호 및 인증 관련 필드와 메서드만을 제공 하며,
    • 사용자 정의 필드를 추가하여 완전한 User 모델을 구성 가능

  • 1. class UserManager(BaseUserManager):

    • user = self.model → class User의 User을 의미
  • 2. class User(AbstractBaseUser):

    • is_active = models.BooleanField(default=False)
      • 활성화 되어있지 않으면 로그인 불가, 기본적으로는 비활성화
      • 이메일이 인증되면 활성화
    • is_admin = models.BooleanField(default=False)
      • 어드민 사이트 들어갈 수 있는 기능
    • user.object.all()
      • object = manager
    • @property
      • 함수인데 클래스 변수처럼 사용가능하게 만들어줌
      • user.is_superuser() 아니라 / user.is_superuser 이렇게 사용 가능하게 해줌
    • def is_staff / def is_superuser
      • is_staff = model.BooleanField(default=False)
      • is_superuser = model.BooleanField(default=False) 처럼 사용도 가능
  • 3. settings 에 model.User 등록

    • INSTALLED_APPS = ['model',]
    • AUTH_USER_MODEL = 'member.User'
      • 기본적으로 장고의 User이 아닌 member의 User모델을 사용한다고 장고에게 인식 시킴
  • 4. migrate

  • 5. 필수 기능 추가 설치

    • poetry add django-extensions
      • settings에 INSTALLED_APPS = [ 'django-extensions' ] 등록
    • poetry add ipython
  • 6. admin 페이지 확인

    • python manage.py createsuperuser
      • models.py 에서 이메일,비밀번호만 묻게 해놔서 두개만 필요

회원가입

  • 1. 정적 데이터를 사용을 위해 static 폴더를 manage.py 와 같은 경로에 생성

    • settings.py 에서 설정코드를 추가
      • STATICFILES_DIRS = [ STATIC_DIR, ] : 개발할때 사용
      • STATIC_ROOT = BASE_DIR / '.static_root' : 배포할때 이용
    • 부트스트랩 에서 CSS와 JS 파일을 다운받아 static 폴더에 넣기
  • 2. forms.py 를 생성하여 회원가입 폼을 커스텀

    • models.py 가 이전이랑 다르게 기본이 username 가 아닌 email
    • from member.models import User / User = get_user_model() 같은 효과
      • get_user_model()
        • settings에 등록한 AUTH_USER_MODEL를 가져오거나 없으면 장고 기본 모델을 가져옴
  • 3. settings.py 설정

    • 3-1. views.py, base.html, signup.html 작성
    • 3-2. urls.py 설정

  • 4. 회원가입 페이지 다듬기

  • 에러 처리

    • password common 같은거 뜨게 함
      • class="text-danger" → 오류메세지를 빨간색으로 나오게 함

  • 부트스트랩 디자인 추가

  • 5. 회원가입 성공시 이동할 signup_done.html 작성

    • success_url = reverse_lazy('signup_done')
      • success_url은 reverse 가 아닌 reverse_lazy 필요
  • 페이지 넘어가는거 까지는 가능한데 DB에 아직 저장 안됨

  • success_url = reverse_lazy('signup_done') 대신 form_valid에서 렌더링

    • 이전 코드에서는 회원가입을 하지 않아도 /signup/done가 들어가 졌지만 안되게 변경
      - 이제 회원가입 완료 링크: http://127.0.0.1:8000/signup/

환경변수 관리

  • 환경변수는 민감한 정보를 코드에서 분리하여 노출을 최소화
    • 환경에 따라 설정을 쉽게 변경할 수 있어 코드 수정 없이 다양한 환경에 대응 가능
    • 개발 팀 내에서 동일한 코드를 사용하되, 각자 환경에 맞는 설정을 사용할 수 있어 협업이 원활
      • GitHub에 올릴 때는 .gitignore 파일을 이용하여 푸시하지 않을 수 있음

python-dotenv

  • python-dotenv 공식문서

    • 파이썬 애플리케이션에서 환경변수를 쉽게 관리하기 위한 라이브러리
      • .env 파일에 저장된 환경 변수를 자동으로 불러와서 파이썬 코드 내에서 사용 가능하게 함
  • 주요기능

    • 환경 변수 관리
      • .env 파일에 환경 변수들을 정의하고, 이를 코드에서 쉽게 불러와서 사용 가능
    • 보안성
      • API 키나 데이터베이스 비밀번호 같은 민감한 정보를 소스 코드에 직접 작성하지 않고
      • .env 파일로 분리함으로써 보안 강화 가능
    • 유연성
      • 개발, 테스트, 프로덕션 환경 간의 설정 차이를 쉽게 관리
  • 사용 예시

    • 설치: pip install python-dotenv
    • .env 파일 생성: 프로젝트 루트에 .env 파일을 생성하고, 환경 변수를 작성
      • DATABASE_URL=postgres://user:password@localhost:5432/mydatabase
      • SECRET_KEY=mysecretkey
  • 파이썬 코드에서 사용

from dotenv import load_dotenv
import os

load_dotenv()  # .env 파일의 환경 변수를 불러옵니다

database_url = os.getenv('DATABASE_URL')
secret_key = os.getenv('SECRET_KEY')

print(f"Database URL: {database_url}")
print(f"Secret Key: {secret_key}")

config_secret

  • .config_secret

    • 디렉토리를 생성해서 환경변수를 관리: 민감한 정보를 안전하게 보관하고 코드와 환경 설정을 분리 쉬움
  • secret.json

    • json 형태로 정보를 관리: 여러 개의 DB를 한 곳에 묶거나의 방식을 통해 관리가 용이
    • 이 때는 파일을 읽어와서 json.loads 라는 명령어를 통해서 json string을 dictionary 형태로 바꿔 사용 가능
  • 사용 예시

import os
import json

# 현재 환경을 지정 (보통 환경 변수로 지정하거나 기본 값을 사용)
current_env = os.getenv('ENV', 'development')

# 해당 환경의 secret.json 파일 경로 설정
secret_file = os.path.join('config_secret', f'{current_env}.json')

# secret.json 파일 로드
with open(secret_file) as f:
    secrets = json.load(f)

# JSON 데이터를 사용해 환경 변수를 설정합니다.
DEBUG = secrets['DEBUG']
DATABASE_URL = secrets['DATABASE_URL']
SECRET_KEY = secrets['SECRET_KEY']

print(f"DEBUG: {DEBUG}")
print(f"DATABASE_URL: {DATABASE_URL}")
print(f"SECRET_KEY: {SECRET_KEY}")

이메일 인증 기능

  • 이메일 SMTP(Simple Mail Transfer Protocol) 설정

    • 애플리케이션에서 이메일을 보내기 위해 사용하는 방법
    • SMTP 서버를 통해 이메일을 발송할 수 있도록 설정하는 과정
  • SMTP 설정에 필요한 정보

    • 일반적으로 이메일 발송을 위해 아래와 같은 정보가 필요
      • SMTP 서버 주소
        • 이메일 서비스를 제공하는 서버의 주소 (예: smtp.naver.com)
      • SMTP 포트 번호
        • 서버가 사용하는 포트 번호 (TLS 사용 시 보통 587, SSL 사용 시 465)
      • 이메일 주소
        • 발신자 이메일 주소
      • 이메일 비밀번호 또는 앱 비밀번호
        • 해당 이메일 계정의 비밀번호. 보안상의 이유로 앱 비밀번호를 사용하는 것이 권장됨.
      • TLS/SSL 사용 여부
        • 이메일 전송 시 암호화할지 여부
  • SMTP 설정방법(NAVER 기준)

  • 네이버 SMTP 이메일 보내기 필수 설정 2가지

    • 네이버 메일 환경설정에서 "IMAP/POP3 사용"을 켜야 함
    • 네이버 SMTP는 반드시 “앱 비밀번호(2단계 인증)” 사용해야 함
  • SMTP 서버 설정

    • EMAIL_HOST = 'smtp.naver.com' ( SMTP 서버 주소 (naver 예시))
    • EMAIL_USE_TLS = False ( TLS 사용 여부)
    • EMAIL_PORT = 465 ( TLS 포트 번호)
    • EMAIL_USE_SSL = True
      • ( SSL을 사용하는 경우 True로 설정하고, EMAIL_PORT는 465로 변경)
  • 이메일 계정 설정

    • EMAIL_HOST_USER = 'your_email@naver.com' ( 발신자 이메일 주소)
    • EMAIL_HOST_PASSWORD = 'your_password' ( 이메일 비밀번호 (또는 앱 비밀번호))
  • 기본 발신자 이메일 주소

    • DEFAULT_FROM_EMAIL = 'your_email@naver.com'
In [1]: from django.core.mail import send_mail

In [2]: title = '제목임'

In [3]: message = '이것은 내용입니다'

In [4]: from_email = settings.EMAIL_HOST_USER

In [5]: to_email = ['nike000112@naver.com']

In [6]: send_mail(title, message, from_email, to_email)
  • 실제 입력해보기


이메일 인증 기능 2


Login, Logout

  • authenticate
    • Django의 기본 인증 메서드로, 주어진 자격 증명(이메일과 비밀번호)으로 사용자를 인증
    • 인증 성공 시 User 객체를 반환하며, 실패 시 None을 반환
  • LoginForm
    • forms.Form을 상속받아 사용자 로그인에 필요한 폼을 정의합니다. 폼은 이메일과 비밀번호를 입력받으며, 각각의 필드에 대한 위젯과 검증 로직을 포함하고 있습니다.
  • class LoginForm(forms.Form)

    • required = True : 무조건 입력을 받겠다
  • forms.py 에 코드를 추가함으로써 form_valid 를 간략하게 줄일 수 있음

  • login페이지 만들기

  • logout 페이지 및 디자인 다듬기


day 9 🙂

Post 생성 수정페이지 구현

Swiper.js / Waypoints / Jquery / 댓글 모델


post 기능 구현하기

  • post app 생성 및 settings에 등록

필요한 기능

  • 이미지 여러개(FK) / 글 / 작성자 / 작성일자 / 수정일자

Post Model

  • 작성일자, 수정일자는 공통적으로 사용될 필드
    • TimestampModel (추상기반 클래스)로 생성하여 활용 (utils/models.py)
  • image = models.ImageField
    • 이미지를 한장만 넣을 경우 사용 가능
  • def str(self):
    • 필수 X , admin페이지에서 편하게 보기위해 사용함

  • 미디어 경로 변경하기

    • settings.py 에 MEDIA_URL 추가 및 urls.py에서 연결
  • Django - 8 에서 적어놨던 TODO 해결


Post 목록 페이지 만들기

  • 디자인 조금 pt -3

  • related_name = images를 상용하여 url을 줄인다

    • class = "img_fluid" : 이미지의 크기가 최대를 넘지 않게 함
  • lg 가 붙은건 큰 화면일때의 크기

Swiper.js

  • Swiper
    • 현대적이고 강력한 이미지 캐러셀 라이브러리, 다양한 옵션과 기능을 제공하며 반응형 디자인을 지원
  • swiper-pagination
    • 슬라이더 하단에 페이지네이션을 표시하여 사용자가 현재 슬라이드의 위치를 확인할 수 있게 함
  • 사용자에게 포스트 별로 업로드된 이미지들을 슬라이드 형태로 보여줄 수 있음
    • Swiper.js
      • 매우 유연하고 다양한 커스터마이징 옵션을 제공
      • 필요에 따라 슬라이더의 동작 방식이나 스타일을 조정할 수 있음

1

  • 양 옆으로 슬라이드 가능

  • 이미지 크기 변경 및 무한슬라이드 끄기

  • BootStrap Docs

  • <meta name="viewport" content="width=device-width, initial-scale=1">

    • 모바일로 들어온 화면 개선?

2 font awesome

  • linebreaksbr : 내용 줄넘김 기능 추가

  • Post.objects.all().select_related('user').prefetch_related('images')
    • DB 부하를 줄이기 위하여 select_related / prefetch_related 사용
      • select_related
        • Post 가 ForeignKey를 가지고 있으면 사용 가능
          • JOIN
      • prefetch_related(역참조)
        • PostImage 가 ForeignKey로 Post를 가지고 있을때 사용
        • ManyToMany 일때 사용
          • 연관되어 있는거 가져옴

전체적인 구조

  • for 루프를 사용해 각각의 Post 객체와 해당 포스트에 연결된 PostImage 객체들을 렌더링
    • 이를 통해 여러 개의 이미지가 슬라이더로 표시
  • 이미지 슬라이드 하단에 페이지 번호 또는 도트(dots) 형식의 페이지네이션이 표시

Post 목록 무한 스크롤 만들기

Waypoints 라이브러리

  • 스크롤 위치를 감지하여 특정 이벤트를 발생시키는 기능을 제공
    • 무한 스크롤을 구현하는 데 유용하게 사용 가능

  • list.html 에 {% load static %} 추가하고 시작

  • post가 가지고 있는 image를 가져와서 post를 새로 만들고 가져온 이미지를 돌면서

    • 새로운 포스트를 만들어줌

jquery

  • JavaScript 를 좀더 간단하게 사용할 수 있게 해주는 패키지 ('$')

  • 다운로드 눌렀을때 나오는거 전체 복사

    • 현재 프로젝트의 static/js/jquery.min.js 파일에 복사한 내용 붙여넣기


포스트 생성, 수정 페이지 만들기

jquery.formset

  • Django와 함께 사용할 수 있는 JavaScript 라이브러리
    • Django의 폼셋(Formset) 기능을 클라이언트 측에서 동적으로 추가하거나 삭제하는 기능을 제공
      • 폼셋(Formset)
        • 같은 형태의 여러 폼을 하나의 폼 그룹으로 관리할 수 있는 Django의 기능
    • jquery.formset은 이를 더욱 사용자 친화적으로 만들어 주는 도구

jqery.formset.js 파일 / jquery.formset.min.js


create

  • 오류발생
    • 해결: form_class=PostForm 추가

디자인 다듬기

  • utils/forms.py 생성
    • create의 본문 칸 줄이기 및 마우스로 본문 칸 조절 불가능 하게 설정
    • 사이즈 수정

1 (query.formset 적용)

  • static/js/jquery.formset.js 에 위의 파일 복사 붙여넣기
    • extra: 기본적으로 추가할 자식 폼의 수를 설정
    • can_delete: 자식 폼의 삭제 여부를 설정

2

  • 이미지 파일 추가하는 기능 추가

  • form_valid 수정

  • prefix = images 인 이유


Update

  • 생성 버튼 만들기

inlineformset_factory

  • Django에서 모델의 폼셋을 생성하는 유용한 도구
    • 부모 모델과 자식 모델 간의 관계를 다루는 폼셋을 자동으로 생성 가능
      • 주로 부모 모델과 관련된 여러 자식 모델 인스턴스를 한 번에 편리하게 관리할 때 사용
      • 주로 부모 모델과 자식 모델 간의 ForeignKey 관계를 관리하는 데 사용
    • 부모 모델의 인스턴스를 편집할 때 자식 모델의 인스턴스도 함께 관리할 수 있는 폼셋을 자동으로 생성

formset.management_form

  • Django의 폼셋(Formset)을 처리할 때 중요한 역할을 하는 관리 폼(Management Form)
    • 이 관리 폼은 폼셋의 여러 폼을 관리하고, 폼셋의 상태를 유지하는 데 필요한 정보를 제공

역할과 중요성

    1. 폼셋 상태 관리
    • 관리 폼은 폼셋의 상태를 관리하기 위해 사용
    • 이상태 정보에는 폼셋의 총 폼 수, 현재 폼 수, 추가된 폼의 수 등
      • 폼셋이 제대로 작동하는 데 필요한 메타 정보가 포함
    1. 폼셋 내 폼 수 조정
    • 관리 폼은 폼셋의 extra 폼 수(즉, 기본적으로 추가할 폼 수)와
      • 삭제된 폼 수를 서버로 전송하는 데 사용, 이는 폼셋의 각 폼이 제대로 처리되도록 함
    1. 폼셋 데이터 처리
    • 관리 폼은 폼셋 데이터와 관련된 정보(예: 폼의 순서, 삭제 플래그 등)를
      • Django가 올바르게 처리할 수 있도록 돕는다.

댓글 모델 만들기, 태그 모델 만들기

  • 태그 : N:N 구조

profile
안녕하세요.

0개의 댓글