테스트 코드: 링크
ListCreateAPIView에 다음과 같이 현재 기준으로 30초 이전 product까지 출력할 수 있는 queryset을 만들었습니다.
class ProdcutListView(ListCreateAPIView):
queryset = Product.objects
.filter(created_at__range = [datetime.datetime.now() - datetime.timedelta(seconds=30) , datetime.datetime.now()])
serializer_class = ProdcutSerializer
datetime.datetime.now() 의 값은 현재 시간이니 API를 요청하는 시점의 시간으로 설정되기를 기대하고 작성한 쿼리입니다.
하지만 결과를 보면 알겠지만 시각이 고정되어 있는 것을 알 수 있습니다.
(0.000) SELECT "products"."id", "products"."name", "products"."code", "products"."created_at" FROM "products"
WHERE "products"."created_at"
BETWEEN '2021-11-17 18:47:45.199577' AND '2021-11-17 18:48:15.199588';
[17/Nov/2021 18:49:11] "GET /products HTTP/1.1" 200 13483
(0.000) SELECT "products"."id", "products"."name", "products"."code", "products"."created_at" FROM "products"
WHERE "products"."created_at"
BETWEEN '2021-11-17 18:47:45.199577' AND '2021-11-17 18:48:15.199588';
[17/Nov/2021 18:49:12] "GET /products HTTP/1.1" 200 13483
(0.000) SELECT "products"."id", "products"."name", "products"."code", "products"."created_at" FROM "products"
WHERE "products"."created_at"
BETWEEN '2021-11-17 18:47:45.199577' AND '2021-11-17 18:48:15.199588';
[17/Nov/2021 18:49:12] "GET /products HTTP/1.1" 200 13483
저 시간은 아래 로그를 자세히 보면 서버가 켜진 시각인것을 알 수 있습니다.
November 17, 2021 - 18:53:06
Django version 3.2.5, using settings 'genericview_queryset_test.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
(0.000) SELECT "products"."id", "products"."name", "products"."code", "products"."created_at" FROM "products"
WHERE "products"."created_at"
BETWEEN '2021-11-17 18:52:36.668389' AND '2021-11-17 18:53:06.668400';
만약 이러한 시간에 따라서 변동되는 값에 대해서 queryset을 세팅하고 싶으면, get_queryset() 함수로 재 정의 하면 됩니다.
def get_queryset(self):
return Product.objects.filter(created_at__range = [datetime.datetime.now() - datetime.timedelta(seconds=30) , datetime.datetime.now()])
둘의 차이점은 쿼리가 만들어지는 시점 인것 같습니다.
내부적으로는 get_queryset() 이 호출되고 그 안에서 만약 현재 사용하고 있는 view에 queryset이 정의가 되어 있으면 queryset을 사용하는 로직으로 되어 있습니다.
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
그래서 get_queryset()을 활용하면 queryset이 필요할때 마다 queryset을 만들기 때문에 유동적으로 변하는 값(시각)에 대해서 대응이 가능한 것 같습니다.
일반적으로는 이러한 경우를 고려하지 않아도 될 것으로 생각됩니다.
(0.000) SELECT "products"."id", "products"."name", "products"."code", "products"."created_at" FROM "products"
WHERE "products"."created_at"
BETWEEN '2021-11-17 19:00:01.069274' AND '2021-11-17 19:00:31.069285';
[17/Nov/2021 19:00:31] "GET /products HTTP/1.1" 200 13483
(0.000) SELECT "products"."id", "products"."name", "products"."code", "products"."created_at" FROM "products"
WHERE "products"."created_at"
BETWEEN '2021-11-17 19:00:02.932611' AND '2021-11-17 19:00:32.932622';
[17/Nov/2021 19:00:32] "GET /products HTTP/1.1" 200 13483
(0.000) SELECT "products"."id", "products"."name", "products"."code", "products"."created_at" FROM "products"
WHERE "products"."created_at"
BETWEEN '2021-11-17 19:00:04.581676' AND '2021-11-17 19:00:34.581689';
[17/Nov/2021 19:00:34] "GET /products HTTP/1.1" 200 13483