Django | WeStagram 7. 게시물 등록

김민호·2021년 10월 3일
1

DJANGO

목록 보기
9/18
post-thumbnail

게시물 등록 기능 준비

posting APP 생성

Django에서는 주로 다루는 데이터의 종류가 달라지는 시점에서 앱을 분리합니다. 인스타그램의 게시물은 이용자 데이터와는 그 성질이 달라 데이터베이스에서 테이블을 따로 관리합니다. 따라서, 주로 다루는 테이블이 달라지므로 앱을 분리하는 것이 좋습니다.

  • python manage.py startapp posting
  • settings.pyINSTALLED_APPSposting 앱 추가

posting MODEL 생성

  • 인스타그램에 게시물을 등록하기 위해서는 작성자, 이미지, 내용이 필요하고 추가적으로 생성시간업데이트시간도 추가해주었다
  • content : 게시물 내용이고, 인스타그램 게시물등록에서 이미지만 필수고
    내용은 필수가 아니기 때문에 null=True값을 주었다
  • updated_at - auto_now=True : model이 갱신될 때마다. 최종수정일자
  • created_at - auto_now_add=True: model이 처음 저장되었을 때 적용
  • 중요한 부분 ⭐️
  • 한 명의 user가 여러 개의 게시물을 등록할 수 있기 때문에 UserPost1 : N 관계이다.그래서User 클래스와 FK로 연결해주었다
  • posting 앱의 Post 클래스가 users 앱의 User 클래스를 참조하게 하기 위해 ForeignKey 필드에 users.User를 인자로 받았다
  • User 클래스를 사용하기 위해서는 import User로 import 해준다
  • on_delete=models.CASCADE : 삭제될 시 삭제
  • related_name='posts' : 역참조를 하는 방법

  • 하나의 게시물에는 여러 개의 이미지가 등록될 수 있다는 점에서 PostImage1 : N 관계이다. 그래서 Image 클래스를 따로 만들고 Post 클래스와 FK로 연결해주었다
  • model 작성이 완료되면 makemigrations 와 migrate를 해준다

로그인 데코레이터(login_decorator)

PostView 를 작성하기 전에

  • 게시물 작성은 로그인이 선행되어 있는 사용자만 가능하기 때문에 login_decorator를 만들고 메소드가 실행될 때마다 선행되도록 하자
  • 로그인 데코레이터는 로그인 토근을 확인시켜주는 역할을 한다.
  • 백엔드에서 로그인에 성공한 사용자에게 토큰을 발행해주고 프론트엔드에서는 이 토큰을 local storage나 session storage에 담아둔다. 그리고 새로운 요청을 할 때마다 header에 넣어서 보내주면 로그인된 상태가 유지된다
  • 필요할 때마다 import해서 사용하기 위해 users 앱에 utils.py를 만들어 작성했다(로그인 데코레이터는 사용자 정보와 관련이 있으므로)

전체 코드

코드 분석

  • login_decorator(func) 함수는 데코레이터가 끝나고 나서 수행될 메인함수를 매개변수로 받는다
  • wrapper() 함수의 인자는 인스턴스 자신 self, http 요청인 request, 확장성을 고려한 *args, **kwargs

  • access_token 은 HTTP request의 header에 담긴 Authorization 값을 가져온다. get 메소드로 받아오기 때문에 해당값이 없으면 None을 반환한다
  • payload : 페이로드는 토큰을 디코딩하면 나오는 사용자에 대한 정보이다. 동일한 사용자라면 동일한 payload 가 반환된다. 디코딩 개념은 여기
  • User 객체(=데이터베이스)에서 id가 payload['id']인 값을 user라는 변수에 저장.
  • request의 user라는 변수를 지정하고 위에서 불러온 유저 정보 객체를 담는다. 이 개체는 데코레이터 이후에 실행되는 다음 함수에서 사용된다 (여기서는 게시물 작성 함수가 될 것) 토큰 정보를 확인하는 HTTP Request에는 토큰을 제외하고는 사용자 정보가 들어오지 않기 때문에 이 user값을 request에 저장해서 이후 활용하는 것. request는 가변객체이기 떄문에 다른 객체나 변수 할당이 가능하다

  • jwt.exceptions.DecodeError : 토큰이 손상되었거나 전달된 토큰 값이 없을 때 발생. decode시에 사용하는 시크릿키나 알고리즘이 다르다면 decode가 불가능하기 떄문에 이런 상황에 발생하는 에러
  • User.DoesNotExist : 토큰에서 디코드된 사용자 정보가 데이터베이스에 존재하지 않을 때 발생

게시물 등록 코드 작성

전체 코드

코드 분석

1.

  • data에는 request.body에 담긴 값을 json형태로 저장한다
  • user에는 User request.user 값이 할당되어 있는데 이 값은

    데코레이터 함수에서 설정되어 있던 값으로 payload에서 Key가 id인 값이다
  • content에는 http 요청으로 받아온 데이터의 content를 담는다
  • image_list 에는 마찬가지로 데이터의 image를 담는데 split(',') 메소드를 통해 ,써서 일렬로 나열한다

2.

  • 이제 Post 클래스를 통해 인스턴스를 생성할 것이고 컬럼은 models.py에서 작성했던 contentuser 두 가지이다.
  • 그리고 Image 인스턴스도 생성할건데 이미지는 한 게시물에 여러 개의 이미지가 있으므로 for문을 통해 생성해준다

3.

  • 성공 시, 키에러 시 각각 메세지 반환

전체 게시물 조회 코드 작성

전체 코드

코드 분석

1.

  • 게시물을 조회할 때, 전체 게시물을 조회할 수도 있고 특정 유저의 게시물을 조회할 수 있다. 먼저 비교적 쉬운 전체 게시물 조회부터 해보자
  • 리스트 컴프리헨션 을 통해 모든 게시물의 정보를 리스트에 담는다
  • Post.objects.all()을 통해 Post의 모든 정보를 QuerySet으로 반환하고 for문을 통해 객체를 하나씩 post에 할당하여 post_list에 딕셔너리 형태의 요소로 담긴 리스트를 만든다.

2.

  • username 에는 User객체에서 id값이 post.user.idname이 값을 할당한다
  • content에는 위에서 생선한 post 인스턴스의 content를 할당
  • images는 한 게시물에 여러 개의 이미지가 있는 것이기 때문에 이것도 리스트 컴프리헨션으로 모든 이미지를 불러와서 그 이미지의 url을 리스트에 담아준다
  • created_at은 post 인스턴스의 created_at를 담는다
  • 문제가 없을시 모든 게시물의 정보가 담긴post_list 를 반환한다

통신 테스트

1. 회원가입

2. 로그인 후 토큰 발행

3. 발행된 토큰으로 게시글 작성

4. 작성된 전체 게시글 조회

profile
개발자로서의 삶은 https://velog.io/@maxminos 에서 기록하고 있습니다 😀

1개의 댓글

comment-user-thumbnail
2022년 3월 22일

정말 설명을 너무 잘해주시고 쫀쫀하다 못해 맛깔난 코드였습니다.

답글 달기