Today I Learned
내가 맡은 부분은
마이페이지에서 내가 쓴 리뷰조회, 예약 조회 / 숙소 상세보기 & 리뷰 조회 / 리뷰 CRUD
=> 전체적인 구현은 완료했고, 로그인 시 예외처리만 남음 + 추가기능 생각 중!
오늘 기능 구현 중에 에러난 부분에 대해서 포스팅
문제 발생 :
def post(self, request, review_id):
room = get_object_or_404(Rooms, id=review_id)
serializer = ReviewCreateSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save(room = room)
해당 숙소에 대한 리뷰를 create할 때 위 코드와 같이 작성했는데
django.db.utils.IntegrityError: NOT NULL constraint failed: users_review.user_id
와 같은 에러가 발생했다.
원인:
- 'NOT NULL constraint failed'는 데이터베이스 필드에 null 값을 허용하지 않기 때문에 필드에 null이 입력되려고 했고, 에러가 발생함
- 현재 Review모델의 user필드가 외래키로 되어있고, 'on_delete'의 옵션이 CASCADE로 설정이 되어있어서 필드가 null이 되는 것을 허용하지 않기 때문에 사용자를 지정해줘야 한다.
그러나 현재 유저를 사용하지 않은 상태에서 로직을 짜고 있기 때문에 밑의 코드와 같이 일반적인 로직처럼 request.user를 사용자로 지정하면
def post(self, request, review_id):
room = get_object_or_404(Rooms, id=review_id)
serializer = ReviewCreateSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save(room = room, user=request.user)
ValueError: Cannot assign "<django.contrib.auth.models.AnonymousUser object at 0x0000013EA24E50A0>": "Review.user" must be a "User" instance.
밸류 에러가 발생한다.
해당 오류는 Review모델의 user필드에 AnonymousUser인스턴스를 할당하려해서 발생한 오류.
request.user가 누구인지 알 수 없기 때문이다.
그렇다면 유저모델 파트가 완성되기 까지 나는 임의로 사용자를 지정해서 테스트 하기로 했다.
시도 1)
#models.py
class Review(models.Model):
user = models.ForeignKey('users.User', on_delete=models.CASCADE, default=1)
booked = models.ForeignKey('rooms.Book',on_delete=models.CASCADE, related_name='booked_users', default=1)
room = models.ForeignKey('rooms.Rooms', on_delete=models.CASCADE, related_name='reviews')
null값이 들어가면 안되는 user와 booked 필드에 default 값을 임의로 넣어줘서 실행하니 잘 작동되었다.
room또한 외래키로 Rooms모델을 참조하고 있지만, view에서 review_id와 같은 id로 지정되어 Rooms모델의 인스턴스가 자동으로 할당된다. 때문에 defaul값이 필요없다.
하지만 이런식으로 모델에 default값을 넣는 것은
- 데이터베이스의 무결성을 깨트린다.
- 추후 데이터 처리에 문제가 될 수도 있다.
이런 연유로 인하여 가능한 defaul값을 넣지 않고 싶어서 방법을 좀 더 찾아보았다.
시도 2)
def post(self, request, review_id):
room = get_object_or_404(Rooms, id=review_id)
serializer = ReviewCreateSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save(room = room, user = User.objects.all().order_by("?")[0]) #모든 유저 랜덤 정렬 하고 1번째 유저 가져오기
serializer를 save할 때, User모델에서 모든 데이터를 가져온 후, 무작위로 정렬한 1번 째의 유저를 가져와서 user변수에 할당해주었다. 쉽게 말하면 User모델에서 임의의 유저를 가져와서 테스트에서 사용하는 것
=> 유저기능이 구현되지 않는 현재 상황에서 테스트용으로 사용!
'내일배움캠프 > 내일배움캠프 TIL' 카테고리의 다른 글
내일배움캠프 TIL 44일차 (0) | 2023.05.12 |
---|---|
내일배움캠프 TIL 43일 - 토스페이 API (1) | 2023.05.11 |
내일배움캠프 TIL 41일차 (4) | 2023.05.08 |
내일배움캠프 TIL 40일차 (0) | 2023.05.06 |
내일배움캠프 TIL 39일차 (0) | 2023.05.06 |