Westagram with Django 3일차

오늘 작업한 것 :

  1. mission 1 ~ 3 Feedback 수정
  2. mission 4 ~ 5 수행

1. mission 1~3 피드백

  1. models.py email 필드 수정 : 겹칠 수 없는 정보를 커버하는 옵션 추가 ->
from django.db import models

class User(models.Model):
    email    = models.EmailField(max_length=50, unique=True)
  • 해결 : unique 값 넣어서 해결
  1. import 명확히 하기
  • 해결 :
from django.urls import path
from .views      import SignupView, LoginView
# *을 남발하지 않기.
  1. url '/' 문제 :
    (메시지)
 (urls.W002) Your URL pattern '/user' has a route beginning with a '/'. Remove this slash as it is unnecessary. If this pattern is targeted in an include(), ensure the include() pattern has a trailing '/'.

해결 : 장고의 권장사항이다. 그러므로 원래 알던데로 진행하면 된다.(수정 완료)

(프로젝트의 urls.py)
urlpatterns = [
    path('account', include('account.urls')),

]


(앱의 urls.py)
from django.urls import path
from .views      import SignupView, LoginView

urlpatterns = [
    path('/user', SignupView.as_view()),
    path('/login', LoginView.as_view()),    
]
  1. data = json~ 예외처리
  • 해결 : 값을 똑같이 예외 처리 문에 넣어줘서 해결했다. 다행히 코드에는 이상이 없었다.
  1. 코드 로직 :
  • 짜다 보니 user = ~ 변수 선언이 필요하지 않았음. 왜냐면 밑에서 이미 필터 쿼리로 User의 내용들이 있는지 없는지(클라이언트의 요청) 확인하고 있었기 때문.

아직 쿼리를 날린다는 말이 뭔 말인지 잘 이해가 안 되어서 한 불필요한 작업이었음.

  • 정리 :

    -이유 : 이미 User.~를 통해 쿼리를 날려 데이터에서 필요한 자료를 가져올 수 있다. 불필요한 변수였다.
    comment :
    -client에서 들어온 값 중 이메일 필터 쿼리를 날려 존재하는 이메일일 경우인지 확인.
    -(마찬가지로) 비밀번호 필터 쿼리를 날려 존재하는 비밀번호인지 확인.
    -이메일과 비밀번호가 유효한 포맷인지 검사하여 유효하면 값 만들기 진행.

  1. Key Error? :
  • 키 에러란 딕셔너리 형태에서 자주 발생하며 딕셔너리 내부에 존재하지 않는 키를 사용해서 값을 내려고 할 때 나는 에러.

    예시로 만일 데이터가 email=~~ password=~~ 로 오는 것이 아니라 emailadkfj=~~ apsdkfjsa=~~~처럼 키 내용이 잘못 와버리는 경우 예외 처리로 키 에러 냄

2. 미션4 완성

  1. app 설치 후 기본 세팅 : 다루는 데이터가 달라지면 앱을 분리한다.

  2. models.py 완성하기

  • 구축한 것 : 사용자(포린키), 생성시간(실시간),이미지URL
    (코드)
from django.db import models

from account.models import User
# 외부 폴더에서 가져온 클래스. 이거 때문에 한참 헤맴.


class Posting(models.Model):
    upload_time = models.DateTimeField(auto_now_add=True)
    # 실시간을 가져오는 방법, 초까지 기록된다.
    img_url     = models.CharField(max_length=1000)
    user        = models.ForeignKey(User, on_delete=models.CASCADE)
    # 외부 폴더에서 받아온 클래스는 ''를 붙이지 않는다

    class Meta:
        db_table = "postings"    
  1. 게시물 views.py 완성하기

3-1. 등록 클래스
(코드)

import json

from django.views import View
from django.http  import JsonResponse

from .models        import Posting
from account.models import User

class PostingView(View):
    def post(self, request):
        #딕셔너리 모양으로 받아들여진 정보(httpie에 입력한 정보)
        data    = json.loads(request.body)
        user    = User.objects.get(email=data['email'])
        posting = Posting.objects.create(
            img_url = data["img_url"],
            user    = user
            #Time은 알아서 import, 입력 필요 없음.
        )
        return JsonResponse({"message" : "SUCCESS"}, status=200)
  • 이거 하면서 처음으로 httpie 통해 어떻게 리퀘스트 되는지 이해했다.(딕셔너리 형태) 어떻게? : by print
  • models.py에서 시간은 알아서 입력되게 했다. 그래서 httpie에서도 따로 쓰지 않아도 입력된다.
  • 에러 심하게 난 부분 : keyerror
    왜? : httpie에서 내가 키를 설정해놓고 키를 안 썼기 때문.-> 어짜피 account 디렉토리에서 알아서 걸러주는데 괜히 안 썼다.(이메일 그냥 쓰면 데이터베이스에는 키값이 저장되고 불려질 땐 이메일이 나온다.)

3-2. 표출

class ShowView(View):    
    def get(self, request):
        shows  = Posting.objects.all()
        result = []
    
        for show in shows:
            my_dict = {
                'update_time' : show.upload_time,
                'img_url'     : show.img_url,
                'user'        : show.user.email,
            }
            result.append(my_dict)
            
        return JsonResponse({"result" : result}, status=200)
  • 표출도 따로 클래스 지정.
  • 헤맸던 것 : return에서 실제 값 나오게 하는 것. 그냥 딕셔너리 형태로 잘 내면 된다.
  1. URL 설정
    posting/urls.py
from django.urls import path
from .views      import PostingView, ShowView

urlpatterns = [
    path('/posting', PostingView.as_view()),
    path('/show', ShowView.as_view()),    
]

프로젝트 urls.py

from django.urls import path, include

urlpatterns = [
    path('account', include('account.urls')),
    path('posting', include('posting.urls')),
]

특별한 것은 없다.

3. 미션 5

  1. posting app 구현 : 기능이 바뀌면 앱이 바뀌어야 함. 이미 만든 미션4를 응용(게시글과 댓글은 같은 위치에 같은 기능이니까!)

  2. models.py

  • 여기서 중요한 것 : foreign key의 역할을 누가 하고 있느냐?
class Comment(models.Model):
    update_time = models.DateTimeField(auto_now_add=True)
    comment     = models.CharField(max_length=2000)    
    img_url     = models.ForeignKey(Posting, on_delete=models.CASCADE)
    user        = models.ForeignKey(User, on_delete=models.CASCADE)
    
    class Meta:
        db_table = "comments"

이 코드에서는 이미지와 유저가 포린키를 하고 있다. 왜냐면 코멘트가 두 가지를 모두 참조하고 있기 때문.(one to many)

  1. views.py
    (코드)
class CommentView(View):
    def post(self, request):
        data = json.loads(request.body)
        img_url = Posting.objects.get(img_url=data['img_url'])
        user    = User.objects.get(email=data['email'])
        comment = Comment.objects.create(
            comment = data["comment"],
            img_url = img_url,
            user    = user
        )
        return JsonResponse({"message":"SUCCESS"}, status=200)

댓글을 등록해야 하는 것이니 POST이용. 그리고 이미지와 유저가 각각 포린키이니 데이터를 가져오고 코멘트로 크리에이트 함.(포린키만 두 개지 여태 했던 것과 매우 유사)

그리고 코멘트를 보여주는 GET
(코드)

class CommentShowView(View):
    def get(self, request):
        commentshows = Comment.objects.filter(img_url=1)
        # id 값이 1번인 게시글의 등록된 댓글들만(그래서 filter, get아님) 출력
        result = []
        
        for commentshow in commentshows:
            my_dict = {
                'user'    : commentshow.user.email,
                'comment' : commentshow.comment,
            }
            result.append(my_dict)
        
        return JsonResponse({"result" : result}, status=200)
  • 다른건 위스타벅스나 앞에서 한 미션과 동일하지만 차이점이 있다면 1개의 요소에 대한 댓글만(첫번째로 규정) 가져와야 하는 추가 구현 사항이 있었다. 중간 중간 에러가 난 것이 value가 id가 들어가야 한다는 힌트를 얻어서 id값으로 1을 부여하고 뽑았더니 첫 번째 게시글 url 댓글만 나왔다.

그 외 url 추가하는 법은 앞서 한 내용과 유사하여 코드 생략.

크게 에러가 나지 않고 실습을 진행했다. 코드에 점점 익숙해지고 있으니 다음 과제도 잘 실행해보자.

profile
커피 내리고 향 맡는거 좋아해요. 이것 저것 공부합니다.

0개의 댓글