def list(self, request, *args, **kwargs): """ overloading list function, make user_id as a requirement to filter """ user_id = request.query_params['user_id'] tweets = Tweet.objects.filter(user_id=user_id).prefetch_related('user') cached_tweets = TweetService.get_cached_tweets(user_id) page = self.paginator.paginate_cached_list(cached_tweets, request) if page is None: """ if 'user_id' not in request.query_params: return Response('missing user_id', status=400) The above line will be interpreted as following SQL:' select * from twitter_tweets where user_id=xxx order by created_at DESC this SQL query will be using composite index of user_id and created_at """ queryset = Tweet.objects.filter( user_id=user_id).order_by('-created_at') page = self.paginate_queryset(queryset) serializer = TweetSerializer( page, context={'request': request}, many=True, ) # usually response in JSON format should be included in hash # instead of a list return self.get_paginated_response(serializer.data)
def list(self, request, *args, **kwargs): tweets = TweetService.get_cached_tweets( user_id=request.query_params['user_id']) paginated_tweets = self.paginate_queryset(tweets) serializer = TweetSerializersWithCommentsAndLikes( paginated_tweets, context={'request': request}, many=True, ) return self.get_paginated_response(serializer.data)
def test_create_new_tweet_before_get_cached_tweets(self): tweet1 = self.create_tweet(self.user1, 'test tweet') RedisClient.clear() conn = RedisClient.get_connection() key = USER_TWEET_PATTERN.format(user_id=self.user1.id) self.assertEqual(conn.exists(key), False) tweet2 = self.create_tweet(self.user1, 'another tweet') self.assertEqual(conn.exists(key), True) tweets = TweetService.get_cached_tweets(self.user1) self.assertEqual([tweet.id for tweet in tweets], [tweet2.id, tweet1.id])
def test_get_user_tweets(self): tweet_ids = [] for i in range(3): tweet = self.create_tweet(self.linghu, 'tweet {}'.format(i)) tweet_ids.append(tweet.id) tweet_ids = tweet_ids[::-1] RedisClient.clear() conn = RedisClient.get_connection() # cache miss tweets = TweetService.get_cached_tweets(self.linghu.id) self.assertEqual([t.id for t in tweets], tweet_ids) # cache hit tweets = TweetService.get_cached_tweets(self.linghu.id) self.assertEqual([t.id for t in tweets], tweet_ids) # cache updated new_tweet = self.create_tweet(self.linghu, 'new tweet') tweets = TweetService.get_cached_tweets(self.linghu.id) tweet_ids.insert(0, new_tweet.id) self.assertEqual([t.id for t in tweets], tweet_ids)
def list(self, request, *args, **kwargs): user_id = request.query_params['user_id'] cached_tweets = TweetService.get_cached_tweets(user_id) page = self.paginator.paginate_cached_list(cached_tweets, request) if page is None: queryset = Tweet.objects.filter( user_id=user_id).order_by('-created_at') page = self.paginate_queryset(queryset) serializer = TweetSerializer( page, context={'request': request}, many=True, ) return self.get_paginated_response(serializer.data)
def list(self, request, *args, **kwargs): user_id = request.query_params['user_id'] tweets = Tweet.objects.filter(user_id=user_id).prefetch_related('user') cached_tweets = TweetService.get_cached_tweets(user_id) page = self.paginator.paginate_cached_list(cached_tweets, request) if page is None: # select * from twitter_tweets where user_id = xxx # order by created_at desc queryset = Tweet.objects.filter(user_id=user_id).order_by('-created_at') page = self.paginate_queryset(queryset) serializer = TweetSerializer( page, context={'request': request}, many=True, ) return self.get_paginated_response(serializer.data)
def list(self, request, *args, **kwargs): user_id = request.query_params['user_id'] cached_tweets = TweetService.get_cached_tweets(user_id) page = self.paginator.paginate_cached_list(cached_tweets, request) if page is None: # 这句查询会被翻译为 # select * from twitter_tweets # where user_id = xxx # order by created_at desc # 这句 SQL 查询会用到 user 和 created_at 的联合索引 # 单纯的 user 索引是不够的 queryset = Tweet.objects.filter( user_id=user_id).order_by('-created_at') page = self.paginate_queryset(queryset) # many = true means it will return a list of dict serializer = TweetSerializer(page, context={'request': request}, many=True) return self.get_paginated_response(serializer.data)
def list(self, request): """ 重载 list 方法,不列出所有 tweets,必须要求指定 user_id 作为筛选条件 """ user_id = request.query_params['user_id'] # get tweets from redis cache instead of DB cached_tweets = TweetService.get_cached_tweets(user_id=user_id) page = self.paginator.paginate_cached_list(cached_tweets, request) if page is None: queryset = Tweet.objects.filter(user_id=user_id).order_by('-created_at') page = self.paginate_queryset(queryset) serializer = TweetSerializer( page, context={'request': request}, many=True, ) # 一般来说 json 格式的 response 默认都要用 hash 的格式 # 而不能用 list 的格式(约定俗成) # return Response({'tweets': serializer.data}) return self.get_paginated_response(serializer.data)
def list(self, request, *args, **kwargs): user_id = request.query_params['user_id'] cached_tweets = TweetService.get_cached_tweets(user_id) page = self.paginator.paginate_cached_list(cached_tweets, request) if page is None: # 这句查询会被翻译为 # select * from twitter_tweets # where user_id = xxx # order by created_at desc # 这句 SQL 查询会用到 user 和 created_at 的联合索引 # 单纯的 user 索引是不够的 queryset = Tweet.objects.filter(user_id=user_id).order_by('-created_at') page = self.paginate_queryset(queryset) serializer = TweetSerializer( page, context={'request': request}, many=True, ) # 一般来说 json 格式的 response 默认都要用 hash 的格式 # 而不能用 list 的格式(约定俗成) # return Response({'tweets': serializer.data}) return self.get_paginated_response(serializer.data)