-
ValueError: The QuerySet value for an exact lookup must be limited to one result using slicingDjango 2022. 1. 9. 23:08
1차 프로젝트 중에 발생했던 ValueError입니다.
문제는 해결했으나 그 당시에 왜 이런 문제가 발생했는지 이해되지 않아서 캡쳐해두고 지금 다시 읽어보니 이제 이해가 됩니다.
ValueError: The QuerySet value for an exact lookup must be limited to one result using slicing.
ValueError: The QuerySet value for an exact lookup must be limited to one result using slicing. 아래의 코드에서 26번째 줄에 filter를 사용해서 product_option이 QuerySet이 되었습니다.
그런데 32번째 줄의 filter에서 조건으로 QuerySet을 입력해서 생기는 문제였습니다.
32번째 줄에서 에러가 발생하고 있습니다. filter의 조건으로 QuerySet을 사용해서 발생하는 에러입니다. 그래서 처음에는 29번째 줄에서 stock 값을 가져올 수 없어서 임시 방편으로 값을 가져오기 위해서 product_option에 인덱싱을 사용해서 값을 가져왔습니다.
그러다가 32번째 줄에서 ValueError가 발생했습니다.
그래서 print도 찍어보고 구글링도 해본 결과 product_option이 QuerySet이라는걸 알았습니다.
filter(products_options=product_option) 을
filter(products_options__in=product_option) 이라고 바꾸니 문제가 해결되었습니다.
filter의 조건으로 QuerySet을 사용할 경우에는 Django의 in  field lookup을 사용해야 합니다. 문제는 해결했지만 당시에는 왜 __in을 써야하는지도 이해할 수 없었고 사실 filter를 사용해서 나오는 값이 QuerySet이라는 것도 몰랐던것 같고 QuerySet의 값을 어떻게 가져올 수 있는지도 몰랐던 것 같습니다..
당시에 인덱싱을 사용해서 값을 가져올 수 있는걸 알았을 때 [0]만 찍어볼게 아니라 전체 값도 찍어보고 그랬으면
for문을 사용할 생각도 할 수 있지 않았을까라는 생각이 듭니다.
유의사항
그리고 저는 이번에는 사용하지 않은 것이지만 QuerySet의 in 조회를 사용할 때 주의해야 하는 점이 있다고 해서 같이 남깁니다.
* values나 values_list를 사용할 때는 둘 이상이 아닌 하나의 필드만 뽑아야 한다고 합니다!
결론
1. filter를 사용하여 나오는 값의 타입은 QuerySet이다.
2. filter는 SQL의 where 과 같은 역할인데 여기에 QuerySet을 입력하면 위와 같은 ValueError가 발생합니다.
3. 정 filter에 QuerySet을 입력해야 한다면 __in을 사용하여 에러를 해결할 수 있습니다.
아래의 블로그 글들이 정말정말 정리가 잘 되어 있어서 잘 이해할 수 있었습니다.
저처럼 위의 문제를 겪고 계신데 제가 쓴 글로는 이해하기 어려우시다면 아래의 글들을 꼭 읽어보시길 바랍니다.
Django QuerySet Value 에러 해결하기
에러 해결하기 비즈니스 로직을 짜면서 항상 실수하고 많이 접하는 에러가 쿼리셋 슬라이싱 에러이다. 구글링을 해보아도 몇 개의 글 말고는 찾아보기 힘든데, 기억할 겸 한번 정리해보려고 한
dev-jacob.tistory.com
'Django' 카테고리의 다른 글
select_related 와 prefetch_related (0) 2022.04.02 카카오 소셜 로그인 API - update_or_create() (0) 2022.01.15 ManyToManyField 사용법 및 장점 (0) 2022.01.09 TypeError : Field 'id' expected a number but got <User : User object (1)> (0) 2022.01.05 Django 테이블 이름 변경 및 삭제 후 마이그레이션시 에러 (0) 2021.12.28