본문 바로가기

Django/Project

[Project] Ongstagram Service #2


본격적으로 앞 페이지에서 말했던대로 기능들을 구현해보면서 프로젝트를 만들어 보겠습니다.

기본이 되거나 익숙한 부분은 빠르게!! 처리하면서 만들어 봅니다.

 

Code : https://github.com/ghk0409/Ongstagram_feat.instagram


<프로젝트 만들기>

- Pycharm에서 [New Project]를 통해 새로운 프로젝트를 만들어 줍니다.

 + 내가 원하는 프로젝트 이름으로! 저는 'ongstagram'으로 만듭니다.

 + 가상환경도 새롭게 만들어서 적용시켜줍니다.

 

- Django 프로젝트를 위한 기본 세팅을 진행합니다.

 + Pycharm 터미널에서 진행해봅니다!!

# Terminal을 통해 Django를 설치합니다.
pip install django

# Django 프로젝트를 만들어 줍니다.
django-admin startproject config .

# DB를 초기화 해줍니다.
python manage.py migrate

# 관리자 계정을 만들어 줍니다.
python manage.py createsuperuser

 + 여기까지가 기본 프로젝트 세팅 완료입니다.


<Photo App 만들기>

1. 앱 만들기

- 사진 관리를 위해 photo 앱을 만들어 봅니다.

# 앱을 만들기 위한 명령어 startapp
python manage.py startapp photo

 

- 앱을 만들면 바로 settings.py의 [INSTALLED_APPS] 변수에 추가 해줍니다.

 + 다음에 또 추가할 수 있으니까 그 때 가서 편하게 ','(콤마)를 뒤에 붙여주는 습관을 들여봅니다~

# config.settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'photo', # photo를 추가해줄께요!! 그리고 , 콤마를 깨알같이
]

2. 모델 만들기

- 만들어진 앱 photo에 있는 models.py에 모델을 만들어 봅니다.

 + 모델은 항상 클래스 형태로 models.Model을 상속받아 만들어 줍니다.

# photo/models.py
from django.db import models
from django.contrib.auth.models import User

class Photo(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_photos')
    photo = models.ImageField(upload_to='photos/%Y/%m/%d', default='photos/no_image.png')
    text = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

 + Photo 모델은 총 5개의 필드로 만들어집니다.

 + 필드는 언제든지 나중에 더 추가할 수도 있습니다!! (추가할 것 같네요. 느낌상)

 1) author

  : ForeignKey를 사용하여 User 테이블과 관계를 만듭니다.

  : User 모델은 Django에서 기본적으로 사용하는 '사용자 모델'입니다.

  : on_delete 인수는 연결된 모델이 삭제될 경우 현재 모델의 값은 어떻게 할 것이냐를 정합니다.

더보기

** on_delete 인수에 대한 옵션 종류를 간략히 알아봅니다.

종류 동작
CASCADE 연결된 객체가 지워지면 해당 하위 객체도 같이 삭제합니다.
PROTECT 하위 객체가 남아 있다면 연결된 객체가 삭제되지 않습니다.
SET_NULL 연결된 객체만 삭제하고 필드 값을 Null로 바꿔줍니다.
SET_DEFAULT 연결된 객체만 삭제하고 필드 값을 설정해놓은 기본값으로 바꿔줍니다.
SET() 연결된 객체만 삭제하고 ( ) 안에 지정한 값으로 바꿔줍니다.
DO_NOTHING 아무 일도 일어나지 않습니다.

  : related_name 인수는 연결된 객체에서 하위 객체의 목록을 부를 때 사용할 이름을 지정합니다.

   예를 들어, 어떤 유저가 작성한 글을 불러 올 때는 유저 객체에 user_photos의 속성(설정한 이름)을 참조합니다.

 

 2) photo

  : 사진 필드입니다. (ImageField를 사용하죠!!)

  : upload_to 인수는 사진이 업로드 될 경로를 설정합니다.

  : 만약 사진 업로드가 되지 않을 경우에는 default 인수에서 지정한 값으로 대체 해줍니다.

 

 3) text

  : 사진에 대한 설명 텍스트 필드입니다. (TextField를 사용하죠!!)

  : 문자열 길이에 대한 제한은 없습니다. (편하긴한데 프로DB러들은 불편할 수도?? 있으려나요??)

 

 4) created

  : 글 작성 일자를 저장하기 위한 날짜/시간 필드입니다. (DateTimeField를 사용하네요.)

  : auto_now_add 옵션을 넣어주면 객체가 추가될 때, 자동으로 추가된 날짜/시간 값을 설정합니다.

 

 5) updated

  : 글 수정 일자를 저장하기 위한 날짜/시간 필드입니다. (DateTimeField 쓴데요.)

  : auto_now 옵션을 넣어주면 객체가 수정될 때마다 자동으로 수정된 날짜/시간 값을 설정합니다.

 

- Photo 클래스 내부에 옵션 클래스들을 추가해보겠습니다.

 1) Meta 클래스

  : ordering 변수는 해당 모델 객체들의 정렬 기준을 설정하는 옵션입니다.

  : ['-updated']로 설정하면 글 수정 시간의 내림차순으로 정렬 해줍니다.

# photo/models.py
class Photo(models.Model):
    # ... 중략하고 아래 Meta 클래스를 추가 해줍니다.
    class Meta:
    	# 모델 객체들의 정렬 기준 설정 // ['-updated']: updated 내림차순으로 정렬
    	ordering = ['-updated']

 

 2) __str__ 메서드

  : 작성자의 이름과 글 작성일을 출력하기 위한 옵션입니다.

  : 작성자 이름 - 글 작성일 순서로 출력 해줍니다.

   + strftime()안의 형태로 작성일을 출력 해줍니다. (연도-월-일 시간:분:초)

# photo/models.py
class Photo(models.Model):
    # 중략 중략하고 __str__ 메서드 추가!!
    def __str__(self):
    	# 글 작성자와 글 작성일 반환
    	return self.author.username + " " + self.created.strftime("%Y-%m-%d %H:%M:%S")

 

 3) get_absolute_url 메서드

  : 객체의 상세 페이지 주소를 반환 해주는 옵션입니다.

  : 객체를 추가/수정했을 때 이동할 주소를 위해 호출되고 템플릿에서 상세 화면 이동 링크를 만들 때도 호출합니다.

  : reverse 메서드는 URL 패턴 이름을 가지고 해당 패턴을 찾아 주소를 만들어주는 메서드입니다.

   + 아직 상세 페이지 뷰를 만들진 않았지만 미리 설정해줘도 문제는 없으니 'photo:photo_detail'로 지정 해놓습니다.

   + 상세 페이지 뷰를 만들 때 뷰 이름을 꼭 photo_detail로 맞춰줍니다!!

  : args를 이용해 URL 만들 때 필요한 pk값(self.id 값)들을 전달하도록 해줍니다.

# photo/models.py
from django.urls import reverse

class Photo(models.Model):
    # 마찬가지 중략하고 get_absolute_url 메서드 추가!!
    def get_absolute_url(self):
    	return reverse('photo:photo_detail', args=[str(self.id)]

 

- 모델을 완성했으니 DB에 적용을 해줍니다.

 + 아마 바로 makemigrations를 진행하면 새로운 가상환경이라 'photo.Photo.photo: (fields.E210) Cannot use ImageField because Pillow is not installed.'라는 오류가 발생할 겁니다.

 + 오류에서 친절하게도 "ImageField를 적용해주고 싶은데 Pillow가 없어!!"라고 말해주니까 pillow 라이브러리를 먼저 설치해줍니다.

 + makemigrations로 변경사항 기록 -> migrate로 변경사항 DB 적용까지 해봅니다.

# pillow 라이브러리 설치
pip install pillow

# pillow 설치 완료 후, photo에 만든 모델 변경사항 기록하기
python manage.py makemigrations photo

# 변경사항 DB에 적용하기
# 처음 migrate할 때 생성된 0001_initial 파일에 변경사항을 적용해줍니다. (파일 늘리기 노노)
python manage.py migrate photo 0001

3. 관리자 페이지에모델 등록하기

- 관리자 페이지에 모델을 등록하면 모델 관리 뷰를 만들기 전에 모델을 테스트할 수 있습니다.

 + admin.py 파일을 수정해 Photo 모델을 등록해봅니다!!

# photo/admin.py
from django.contrib import admin
from .models import Photo

admin.site.register(Photo)

 

- 모델을 등록한 후, 서버를 실행하여 관리자 페이지에 접속해 줍니다. 그리고 사진 업로드 테스트를 해봅니다.

 + 서버 실행 후, http://127.0.0.1:8000/admin/ 경로로 접속합니다.

# 서버 실행!!
python manage.py runserver

관리자 페이지로 접속하고 [+Add] 버튼을 클릭!!

 

- 추가 화면으로 이동한 후 사진 업로드를 해봅니다.

 + Author는 작성자인데 현재 관리자 계정뿐이니까 관리자 계정으로 해봅니다.

 + 이미지 파일 올려보고 설명도 추가 해봅니다!!

이렇게 넣어주고 SAVE 해줍니다.

 

- 업로드 시켜준 뒤, 다시 Pycharm으로 돌아와보면 photos 폴더가 생겨나고 그 아래로 '연도/월/일' 순으로 하위 폴더들도 생긴 뒤 마지막에 이미지 파일이 추가된 것을 확인할 수 있어요.

노란 박스처럼 추가되면 성공~


4. 업로드 폴더 관리

- 위처럼 진행하고 나서 생각해보니 만약 앱이 photo만 있는게 아니라 여러 개가 있으면 폴더도 너무 많아질지도?? 모른단 걱정이 차오르게 됩니다. 그럴꺼에요.

 + 이를 위해 각 앱에서의 업로드 파일을 한 폴더에서 관리할 수 있도록 해봅니다!!

 

- settings.py에서 [MEDIA_ROOT] 옵션을 설정해줘 봅니다.

 + MEDIA_ROOT 값을 프로젝트 루트 밑의 media 폴더로 설정합니다.

 + 프로젝트 내의 어떤 앱에서 업로드를 하더라도 이제 media 폴더 아래 각 앱 별로 폴더를 만들고 파일을 업로드 할꺼에요.

 + MEDIA_URL은 STATIC_URL처럼 파일을 브라우저로 보내줄 때 보여줄 가상의 URL입니다.

 + 가상의 URL은 편의를 위해 쓰기도 하지만 '보안'을 위해 꼭 필요한 기능입니다!! (내부 폴더 구조를 숨길 수 있거든요)

# config/settings.py
# os 라이브러리가 아직 import 안됐다면 추가!
import os 

# 브라우저로 파일 보낼 때 보여줄 가상의 URL 설정
MEDIA_URL = '/media/'
# media 폴더 밑으로 각 앱별로 파일 업로드하도록 설정
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

다시 한 번 이미지를 업로드하면 media 폴더 아래로 집합!!! 되네요ㅎㅎ

 + 그럼 photos 폴더는 이제 안녕히 잘 가시게요~ 딜리트해 줍니다.


파일 업로드도 너무 간단하게 가능해지고 재밌게 진행이 되네요.

다른 언어였다면.... 역시 GODython 입니다. 거기서도 Django의 편리함이란!!

 

그럼 이어서 관리자 페이지 커스터마이징부터 한 번 들어가보겠습니다~

 

해당 프로젝트는 "베프의 오지랖 파이썬 웹 프로그래밍(디지털북스)"를 참고합니다.

'Django > Project' 카테고리의 다른 글

[Project] Onstagram Service #4  (0) 2021.06.08
[Project] Ongstagram Service #3  (0) 2021.06.07
[Project] Ongstagram Service #1  (0) 2021.06.01
[Project] Ong's BookMark Service #5  (1) 2021.05.29
[Project] Ong's BookMark Service #4  (0) 2021.05.29