본격적으로 앞 페이지에서 말했던대로 기능들을 구현해보면서 프로젝트를 만들어 보겠습니다.
기본이 되거나 익숙한 부분은 빠르게!! 처리하면서 만들어 봅니다.
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
- 추가 화면으로 이동한 후 사진 업로드를 해봅니다.
+ Author는 작성자인데 현재 관리자 계정뿐이니까 관리자 계정으로 해봅니다.
+ 이미지 파일 올려보고 설명도 추가 해봅니다!!
- 업로드 시켜준 뒤, 다시 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')
+ 그럼 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 |