ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TypeError : Field 'id' expected a number but got <User : User object (1)>
    Django 2022. 1. 5. 08:32

    사이드 프로젝트로 'Zara' 클론 코딩을 하고 있습니다.

    그중에서 장바구니 앱을 하던 중에 마주한 에러 메시지에 대해 알아보고자 합니다.

    대부분의 에러메세지가 그렇지만 특히 이번 것은 조금만 읽어보면 에러 메시지에 답이 다 담겨 있습니다.

    제가 'id'에 해당하는 값(number)을 불러오겠다 하고 그곳에 'User' 객체를 가져와서 생긴 에러 메시지입니다.

     

    장바구니 앱을 처음 작성해본 것이라 지저분하고 불필요한 부분이 많아서 보시기 불편하시겠지만 조금 양해 부탁드립니다. 에러 메시지가 발생한 이유와 어떻게 그리고 왜 이렇게 해결된 건지를 집중적으로 보신다면 좋을 것 같습니다.

    TypeError: Field 'id' expected a number but got <User: User object (1)>
    Cart 앱 - models.py

    장바구니 앱을 모델링한 것입니다.

    처음에 유저 1명당 장바구니를 1개만 활성화시키고 싶어서 1:1 관계인 OneToOneField를 사용했는데

    이러면 이미 장바구니에 제품이 있는 유저의 경우 제품 추가가 되지 않는 문제가 있었습니다.

    모델링에 대한 이해가 부족해서 생긴 결과였다고 생각합니다. 물론 프로젝트의 사이즈가 작아서 중간에 수정을 하는 것은 큰 문제가 되지 않았지만 모델링이 프로젝트의 시작 부분이라고 생각하는데 모델링의 관계에 대해 더 알아보고 했어야 했습니다. 저는 1대 1의 관계일 때는 OneToOneField를 사용하고 1대 다일 때 Foreign Key를 쓰는 줄 알았습니다. 그런데 우선은 Foreign Key도 1대 1 관계에서 사용이 가능하고 OneToOneField가 조금 더 사용에 제약이 있는 것으로 봤습니다. 다대다 관계도 굉장히 흥미로웠어서 이런 모델링에 대해서는 조만간 다시 글을 쓰도록 하겠습니다.

    스택오버플로우에서 본 예시인데 어느 정도 해당 모델링에 대해 감을 잡고 계신다면 아래의 글을 통해 해당 개념을 조금 더 가시화시킬 수 있을 것이라고 생각합니다. 

    A ForeignKey is a many-to-one relationship. So, a Car object might have many instances of Wheel. Each Wheel would consequently have a ForeignKey to the Car it belongs to. A OneToOneField would be like an instance of Engine, where a Car object can have one and only one.

    장바구니 앱 - 제품 추가 기능

     

    다시 본론으로 돌아와서 'OneToOneField duplicate key error'가 발생해서 Foreign Key로 바꿨습니다.

    그 후 장바구니 앱 마이그레이션을 진행하는데 다른 앱의 마이그레이션에 문제가 있어서 해당 앱의 마이그레이션 디렉터리에 있는 '__init__. py'를 제외한 마이그레이션 파일들을 삭제한 후에 마이그레이션을 진행하니 문제없이 마무리되었습니다.

    그 후 문제없이 같은 유저일 경우에 제품 추가 및 수량 변경 기능을 구현할 수 있었습니다.

     

    코딩할 때 무언가 푹 빠져서 정신없이 쓰고 테스트하면서 수정하고는 하는데 이렇게 정리할 때 뭔지도 모른 채 쓰고 있었고 나라는 걸 또 한 번 느낍니다.

    같은 에러 메시지가 여러 번 뜨면 캡처해두는 습관을 만들고 있는데 그 후 그 문제를 해결하면 해당 코드를 캡처해서 어떤 부분을 고쳐서 해결된 건지와 그  차이는 무엇일까 찾으면서 배우는 것이 많습니다.

    이 글을 보시는 분들도 자주 마주하게 되는 에러 메시지를 캡처해뒀다가 잘 정리하신다면 좋을 것 같습니다.

     

    해당 앱의 models.py에 있는 클래스의 속성이 Foreign Key로 연결되어 있는데

    객체를 생성할 때  해당 속성을 그대로 쓰면 Foreign Key로 연결되어 있는 해당 클래스의 객체가 와야 합니다.

    아래의 경우(44번째 줄)에는 carts앱의 Cart의 user가 users앱의 User 클래스에 연결되어 있기 때문에

    아래처럼 작성이 되어야 합니다. 

    user = User.objects.get(id=data['user_id']
    
    Cart.objects.create(user=user, ...)
    
    또는
    
    Cart.objects.create(user_id=user.id, ...)
    
    이런 식으로 쓰시면 됩니다.

     

    TypeError 부분 수정

     

     

    OneToOneField와 Foreign Key의 차이점에 대해 스택오버플로우에 있던 글을 위에서 공유했습니다.

    https://stackoverflow.com/questions/5870537/whats-the-difference-between-django-onetoonefield-and-foreignkey

     

    What's the difference between django OneToOneField and ForeignKey?

    What's the difference between Django OneToOneField and ForeignKey?

    stackoverflow.com

     

    댓글

Designed by Tistory.