HTTP request -> urls --> views --> models (DB 관리)
서버를 구현할 때는 동작 순서와 반대로 진행해주는 것이 편리함
models --> views --> urls --> HTTP request
위의 순서대로 구현하기
conda create -n westagram python=3.7
conda activate westagram
pip install django
mkdir westagram
cd westagram
django-admin startproject test1
시작 전 세팅에서 설정하기
vim test1/settings.py
여기서는 관리자 기능 / 인증 기능 (auth) 사용하지 않을 것이므로INSTALLED_APPS, MIDDLEWARE 에서 아래의 admin, auth, csrf(보안관련 내용)관련 내용 주석처리하기
INSTALLED_APPS = [
# django.contrib.admin',
# 'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
# 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
이때 admin기능을 주석처리 했으므로
test1/urls.py 에서 admin 관련 내용도 주석처리 해줘야지 runserver에서 에러 발생하지 않음
회원가입 및 로그인 하는 app 만들기
python manage.py startapp account
vim test1/settings.py에서 app추가해주기
아래와 같이 됨
INSTALLED_APPS = [
# django.contrib.admin',
# 'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account', # 추가한 부분
]
from django.db import models
class Account(models.Model):
name = models.CharField(max_length=200)
email = models.CharField(max_length=200)
password = models.CharField(max_length=400)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)
위의 내용을 추가하여 models.py에 Account라는 class를 만들고 이 class에 email, password, created_date, updated_date를 DB로 생성하게 만듬
(migration 이후에 위의 내용들이 데이터베이스가 됨)
그런데 그냥 migration하면 DB table가 원하지 않는 이름으로 생성되어서 그 전에 데이터베이스의 이름을 먼저 지정해주기
이 과정은 Meta class 이용하기
문자열 charfield
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)
auto_now_add 해주면 최초 기록 때 한번만 기록 (최초정보 시간 기록하는 것)
auto_now 해주면 정보 변화가 발생할 때마다 시간을 기록 (수정정보 시간 기록)
model class 내부에 Meta라는 이름의 클래스를 하나 더 생성해서 만들 수 있음
이를 사용하면 아래와 같이 됨
from django.db import models
class Account(models.Model):
name = models.CharField(max_length=200)
email = models.CharField(max_length=200)
password = models.CharField(max_length=400)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)
class Meta:
db_table = "accounts"
데이터베이스 테이블 이름은 보통 복수로 지정해줌
위에서 만들었던 model을 DB에 추가하기 위해서 migration 진행
python manage.py makemigrations account
python manage.py migrate
위의 과정으로 migration 진행하고 아래의 내용을 입력하여 migration상태를 확인할 수 있음
python manage.py showmigrations
import json
from django.views import View
from django.http import HttpResponse
from .models import Account
class AccountView(View):
def post(self,request):
data = json.loads(request.body)
Account(
name = data['name']
email = data['email']
password = data['password']
).save()
return HttpResponse(status = 200)
http에서 요청 올 때 body에 정보 담아서 옴
http request의 body에 담긴 정보를 json 형식으로 로드해오고 이것을 data라는 변수에 담음
Account(
name = data['name']
email = data['email']
password = data['password']
).save()
요청에 담겨서 온 name, email, password를 저장
위와 같이 입력하면 회원가입 정보를 생성할 수 있음
만약 같은 email로 회원가입을 하면 에러가 발생하도록 만들기
아래와 같이 입력하면 됨
import json
from django.views import View
from django.http import JsonResponse, HttpResponse
from .models import Account
class AccountView(View):
def post(self,request):
data = json.loads(request.body)
if Account.objects.filter(email=data['email']).exists():
return JsonResponse({"message":"no"},status=401)
else :
Account.objects.create(
name = data['name'],
email = data['email'],
password = data['password']
)
return HttpResponse(status=200 )
filter와 exists()를 이용해서 있는 이미 존재하는 이메일인지 확인하고 이메일이 있으면 오류 리턴하고 없으면 회원가입 할 수 있도록
from django.urls import path
from .views import AccountView
urlpatterns = [
path('sign_up',AccountView.as_view())
]
위의 내용을 추가
장고에서 url경로를 처리하기 위한 모듈을 import,
views.py안의 AccountView 클래스를 import 하고
sign_up일 때 AccountView 클래스에 내장된 as_view() 함수 실행
as_view() 메소드는 현재 주소인 나를 호출하면 그 호출을 한 http 메소드가 GET인지 POST인지 DELETE인지 UPDATE인지 등을 판별해서 그에 맞는 함수를 실행시켜줌
Project의 urls.py에 app의 urls 경로 추가해주기
from django.urls import path, include
urlpatterns = [
path('account/', include('account.urls')),
]
path('app이름/', include('앱이름.urls'))와 같은 형식으로 사용함
모델은 회원가입과 같음
이메일로 로그인하도록 함
아래의 내용 추가
.....
class LoginView(View):
def post(self,request):
data = json.loads(request.body)
password = data['password']
if Account.objects.filter(email=data['email']).exists():
if Account.objects.get(email=data['email']).password == password:
return HttpResponse(status=200)
else :
return JsonResponse({"message":"INVALID_USER"},status=401)
else :
return JsonResponse({"message":"INVALID_USER"}, status=401)
먼저 이메일이 존재하는지 찾음 --> 존재하면 해당 이메일 비밀번호와 입력 비밀번호가 같은지 확인
이메일이 존재하지 않으면 오류 발생
from django.urls import path
from .views import AccountView, LoginView
urlpatterns = [
path('sign_up',AccountView.as_view()),
path('sign_in',LoginView.as_view())
]
회원가입하는 url을 추가해줌
test1/urls.py 은 그대로
댓글달기 app 만들기
python manage.py startapp coments
vim test1/settings.py에서 app추가해주기
아래와 같이 됨
INSTALLED_APPS = [
# django.contrib.admin',
# 'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account',
'comments', # 추가한 부분
]
from django.db import models
class Comment(models.Model):
email = models.CharField(max_length=200)
reply = models.TextField()
crated_reply = models.DateTimeField(auto_now_add=True)
updated_reply = models.DateTimeField(auto_now=True)
class Meta:
db_table = "comments"
위와 같이 모델 생성
이때 reply은 TextField로 해줌 TextField는 max_length등 필요 없음!
from django.views import View
from django.http import JsonResponse,HttpResponse
from .models import Comment
from account.models import Account
class CommentView(View):
def post(self,request):
data = json.loads(request.body)
if Account.objects.filter(email=data['email']).exists():
reply_westa = Comment(
email = data['email'],
reply = data['reply']
)
reply_westa.save()
return HttpResponse(status=200)
else :
return JsonResponse({"message":"INVALID_USER"}, status=401)
이메일이 회원가입에서 존재했던 이메일이면 댓글달 수 있도록 설정
존재하는 이메일인지는 filter().exists()를 사용해서 찾음
여기서 Account app의 데이터를 사용하기에 import Account해줌
from django.urls import path
from .views import CommentView
urlpatterns = [
path('reply',CommentView.as_view())
]
위와 같이 경로 설정
from django.urls import path, include
urlpatterns = [
path('account/', include('account.urls')),
path('comments/',include('comments.urls')),
]
project의 url경로에도 app의 경로 추가해주기
comments/models.py는 위와 같음
.....
class MyReplyView(View):
def get(self,request,address):
my_reply= Comment.objects.filter(email=address)
my_reply_list=[]
for i in range(len(my_reply)):
my_reply_list.append(my_reply.values()[i]['reply'])
return JsonResponse({"comment":my_reply_list},status=200)
위의 내용 추가
여기서 get은 address라는 인자를 받음 이 인자는 내 이메일주소
values()내가 쓴 댓글을 리스트에 추가하고 불러오기
from django.urls import path
from .views import CommentView, MyReplyView
urlpatterns = [
path('reply',CommentView.as_view()),
path('myreply/<str:address>',MyReplyView.as_view()),
]
test1/urls.py은 그대로