현재 생성한 User
라는 앱은 게시글을 등록하는 것과는 기능이 다르다. 보통 앱을 구분하는것은 기능별로 구분하기 때문에 Post
라는 새로운 앱을 생성했다.
앱을 새로 생성하면 settings.py
에서 생성한 앱을 등록시키는 절차를 잊지 말자! ( + URL 경로 추가도 )
from django.db import models
from User.models import User
class Post(models.Model):
email = models.ForeignKey(User, on_delete = models.CASCADE)
content = models.TextField(max_length = 300)
image_url = models.URLField()
created_at = models.DateTimeField(auto_now_add = True)
class Meta:
db_table = "posts"
def __str__(self):
return self.email
Post와 관련된 모델들을 정의했다. User 에서 회원가입할 때 이메일을 받았기 때문에, 회원을 구분할 기준이 이메일밖에 없어서 이메일로 정의했고, 게시물의 내용을 저장 할 content
, 게시글에 이미지를 올렸을 때 해당 이미지의 URI을 받기위한 image_url
, 게시글이 작성 된 날짜와 시간을 표시 해 주기 위해서 created_at
을 생성해주었다.
class Meta
부분은 모델을 생성하거나 수정하고나면 migration 작업을 진행해주어야 하는데, migration 작업을 하면 db 테이블이 생성된다. 이 때 생성 될 table의 이름을 지정해주는 역할이다. 만약 이렇게 이름을 지정해주지 않으면 테이블 이름이 App이름_Class이름
으로 django에서 알아서 저장해주기 때문에 굳이 이름을 설정해주고 싶지 않으면 이 부분은 생략해도 좋다.
__str__
부분은 db 테이블에서 하나의 정보를 가져오고 싶으면 해당 row를 전부 가져오게 되는데 그렇게 되면 메모리 낭비가 생기므로, 내가 email이란 정보만 가져오고싶다면 email에 대한 정보만 가져올 수 있도록 이름을 지정해주는 역할을 한다.
모델을 수정하고 나면 makemigration
과 migrate
작업을 잊지 말자
import json
from django.views import View
from django.http import JsonResponse
from User.models import User
from .models import Post
class PostView(View):
def post(self, request):
data = json.loads(request.body)
try:
if User.objects.filter(id = data['user_id']).exists():
user = User.objects.get(id = data['user_id'])
Post(
user = user,
content = data['content'],
image_url = data['image_url'],
).save()
return JsonResponse({'message' : 'SUCCESS'}, status = 200)
else:
return JsonResponse({'message' : 'UNAUTHORIZED'}, status = 401)
except Exception as e:
return JsonResponse({'message' : f'{e}'}, status = 400)
class PostDisplayView(View):
def get(self, request):
post_data = Post.objects.values()
return JsonResponse({'post_data' : list(post_data)}, status = 200)
게시물을 등록해줄 수 있는 PostView
클래스와 등록한 게시글을 볼 수 있는 PostDisplayView
클래스로 두가지의 클래스를 만들었다.
PostView
클래스에서는 models
에서 email
에 지정한 ForeignKey
를 사용해서 서로 연결시켜주었다. id
값에 user_id
값을 넣어주었고, 이 id
값으로 게시글을 등록한 유저를 찾아내는 역할을 한다.
django에서는 Primary Key를 임의로 지정해주지 않으면 default로 Foreign Key와 Primary Key를 동일하게 설정해준다. 따라서 위 코드에서 primary key에 대한 설정을 따로 해주지 않았기 때문에 foreign key와 primay key는 동일한 id값을 참조한다. 그래서 위와 같은 코드가 정상 동작을 한다.
회원가입을 한 유저의 id
값을 받아서 해당 id
가 db에 정상적으로 저장되어 있으면 게시글을 작성했을 때, SUCCESS
메시지를 반환해주고, 회원가입 정보가 없는 유저가 게시글을 등록하려고 하면 권한이 없다는 뜻에 UNAUTHORIZED
라는 문구와 함께 401
코드를 반환해주도록 했다. 그 외의 에러가 발생했을 경우는 해당 에러 자체 이름을 그대로 출력해주며 400
코드를 반환시킨다.
해당 클래스는 게시글을 등록하면 그 내용을 볼 수 있는 GET
방식의 통신을 하는 클래스이다. 게시글에 대한 values
를 받아와서 list
형태로 출력해주도록 하였다.
from django.urls import(
path,
include
)
urlpatterns = [
path('user/', include('User.urls')),
path('post/', include('Post.urls')),
]
Post 앱을 생성했기 때문에 위와 같이 경로를 설정해준다.
from django.urls import path
from .views import (
PostView,
PostDisplayView
)
urlpatterns = [
path('post', PostView.as_view()),
path('postdisplay', PostDisplayView.as_view()),
]
두개의 클래스를 만들었기 때문에 각각의 클래스를 호출하기 위해 경로를 구분지어 위와 같이 작성했다.
해당 코드는 위 if조건문이 만족하지 않아 200이 return 되지 않는다면 바로 도달 하는 코드입니다. 따라서 else가 없어도 됩니다. 꼭 있어야 하는 else가 아니라면 적지 않는 것을 추천드립니다.
try:
if User.objects.filter(id = data['user_id']).exists():
user = User.objects.get(id = data['user_id'])
Post(
user = user,
content = data['content'],
image_url = data['image_url'],
).save()
return JsonResponse({'message' : 'SUCCESS'}, status = 200)
else:
return JsonResponse({'message' : 'UNAUTHORIZED'}, status = 401)
파이썬을 파이썬답게 만들기 위한 습관을 기르고 있는 중이다. if
조건을 만족하지 못하면 else:
를 해주지 않아도 return
문이 동작하기 때문에 꼭 필요한 else
가 아니라면 쓰지 않는것이 조금 더 파이썬을 파이썬답게 쓰는 방법이라고 한다.
리뷰를 받은것은 아니였지만 코드를 수정하다보니 내가 models
에서는 email
로 모델링을 했는데, views
에서는 user
로 구분하고 있는게 맞지 않다고 생각이 들어 email
로 수정을 해주었다.
try:
if User.objects.filter(id = data['user_id']).exists():
email = User.objects.get(id = data['user_id'])
Post(
email = email,
content = data['content'],
image_url = data['image_url'],
).save()
return JsonResponse({'message' : 'SUCCESS'}, status = 200)
return JsonResponse({'message' : 'UNAUTHORIZED'}, status = 401)
파이썬을 파이썬답게 쓰도록 노력하기